diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2020-07-30 18:54:46 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2020-07-30 18:54:46 +0700 |
commit | 6df85c63349e5a0ddc9187de8779443fa8b55963 (patch) | |
tree | c3cca3d575f452ae9d96cdf8880a9610e1af4866 | |
parent | Add generic private key output to openssl (diff) | |
download | BouncyCastle.NET-ed25519-6df85c63349e5a0ddc9187de8779443fa8b55963.tar.xz |
Encoder performance
-rw-r--r-- | crypto/src/util/encoders/Base64Encoder.cs | 162 | ||||
-rw-r--r-- | crypto/src/util/encoders/HexEncoder.cs | 75 |
2 files changed, 155 insertions, 82 deletions
diff --git a/crypto/src/util/encoders/Base64Encoder.cs b/crypto/src/util/encoders/Base64Encoder.cs index 07294c9a6..21e8051d3 100644 --- a/crypto/src/util/encoders/Base64Encoder.cs +++ b/crypto/src/util/encoders/Base64Encoder.cs @@ -44,69 +44,69 @@ namespace Org.BouncyCastle.Utilities.Encoders InitialiseDecodingTable(); } - /** - * encode the input data producing a base 64 output stream. - * - * @return the number of bytes produced. - */ - public int Encode( - byte[] data, - int off, - int length, - Stream outStream) + public int Encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) { - int modulus = length % 3; - int dataLength = (length - modulus); - int a1, a2, a3; + int inPos = inOff; + int inEnd = inOff + inLen - 2; + int outPos = outOff; - for (int i = off; i < off + dataLength; i += 3) + while (inPos < inEnd) { - a1 = data[i] & 0xff; - a2 = data[i + 1] & 0xff; - a3 = data[i + 2] & 0xff; - - outStream.WriteByte(encodingTable[(int) ((uint) a1 >> 2) & 0x3f]); - outStream.WriteByte(encodingTable[((a1 << 4) | (int) ((uint) a2 >> 4)) & 0x3f]); - outStream.WriteByte(encodingTable[((a2 << 2) | (int) ((uint) a3 >> 6)) & 0x3f]); - outStream.WriteByte(encodingTable[a3 & 0x3f]); + uint a1 = inBuf[inPos++]; + uint a2 = inBuf[inPos++]; + uint a3 = inBuf[inPos++]; + + outBuf[outPos++] = encodingTable[(a1 >> 2) & 0x3F]; + outBuf[outPos++] = encodingTable[((a1 << 4) | (a2 >> 4)) & 0x3F]; + outBuf[outPos++] = encodingTable[((a2 << 2) | (a3 >> 6)) & 0x3F]; + outBuf[outPos++] = encodingTable[a3 & 0x3F]; } - /* - * process the tail end. - */ - int b1, b2, b3; - int d1, d2; + switch (inLen - (inPos - inOff)) + { + case 1: + { + uint a1 = inBuf[inPos++]; - switch (modulus) + outBuf[outPos++] = encodingTable[(a1 >> 2) & 0x3F]; + outBuf[outPos++] = encodingTable[(a1 << 4) & 0x3F]; + outBuf[outPos++] = padding; + outBuf[outPos++] = padding; + break; + } + case 2: { - case 0: /* nothing left to do */ - break; - case 1: - d1 = data[off + dataLength] & 0xff; - b1 = (d1 >> 2) & 0x3f; - b2 = (d1 << 4) & 0x3f; - - outStream.WriteByte(encodingTable[b1]); - outStream.WriteByte(encodingTable[b2]); - outStream.WriteByte(padding); - outStream.WriteByte(padding); - break; - case 2: - d1 = data[off + dataLength] & 0xff; - d2 = data[off + dataLength + 1] & 0xff; - - b1 = (d1 >> 2) & 0x3f; - b2 = ((d1 << 4) | (d2 >> 4)) & 0x3f; - b3 = (d2 << 2) & 0x3f; - - outStream.WriteByte(encodingTable[b1]); - outStream.WriteByte(encodingTable[b2]); - outStream.WriteByte(encodingTable[b3]); - outStream.WriteByte(padding); - break; + uint a1 = inBuf[inPos++]; + uint a2 = inBuf[inPos++]; + + outBuf[outPos++] = encodingTable[(a1 >> 2) & 0x3F]; + outBuf[outPos++] = encodingTable[((a1 << 4) | (a2 >> 4)) & 0x3F]; + outBuf[outPos++] = encodingTable[(a2 << 2) & 0x3F]; + outBuf[outPos++] = padding; + break; } + } + + return outPos - outOff; + } - return (dataLength / 3) * 4 + ((modulus == 0) ? 0 : 4); + /** + * encode the input data producing a base 64 output stream. + * + * @return the number of bytes produced. + */ + public int Encode(byte[] buf, int off, int len, Stream outStream) + { + byte[] tmp = new byte[72]; + while (len > 0) + { + int inLen = System.Math.Min(54, len); + int outLen = Encode(buf, off, inLen, tmp, 0); + outStream.Write(tmp, 0, outLen); + off += inLen; + len -= inLen; + } + return ((len + 2) / 3) * 4; } private bool ignore( @@ -128,8 +128,9 @@ namespace Org.BouncyCastle.Utilities.Encoders Stream outStream) { byte b1, b2, b3, b4; + byte[] outBuffer = new byte[54]; // S/MIME standard + int bufOff = 0; int outLen = 0; - int end = off + length; while (end > off) @@ -166,16 +167,32 @@ namespace Org.BouncyCastle.Utilities.Encoders if ((b1 | b2 | b3 | b4) >= 0x80) throw new IOException("invalid characters encountered in base64 data"); - outStream.WriteByte((byte)((b1 << 2) | (b2 >> 4))); - outStream.WriteByte((byte)((b2 << 4) | (b3 >> 2))); - outStream.WriteByte((byte)((b3 << 6) | b4)); + outBuffer[bufOff++] = (byte)((b1 << 2) | (b2 >> 4)); + outBuffer[bufOff++] = (byte)((b2 << 4) | (b3 >> 2)); + outBuffer[bufOff++] = (byte)((b3 << 6) | b4); + + if (bufOff == outBuffer.Length) + { + outStream.Write(outBuffer, 0, bufOff); + bufOff = 0; + } outLen += 3; i = nextI(data, i, finish); } - outLen += decodeLastBlock(outStream, (char)data[end - 4], (char)data[end - 3], (char)data[end - 2], (char)data[end - 1]); + if (bufOff > 0) + { + outStream.Write(outBuffer, 0, bufOff); + } + + int e0 = nextI(data, i, end); + int e1 = nextI(data, e0 + 1, end); + int e2 = nextI(data, e1 + 1, end); + int e3 = nextI(data, e2 + 1, end); + + outLen += decodeLastBlock(outStream, (char)data[e0], (char)data[e1], (char)data[e2], (char)data[e3]); return outLen; } @@ -208,8 +225,9 @@ namespace Org.BouncyCastle.Utilities.Encoders // return bytes.Length; byte b1, b2, b3, b4; + byte[] outBuffer = new byte[54]; // S/MIME standard + int bufOff = 0; int length = 0; - int end = data.Length; while (end > 0) @@ -246,16 +264,32 @@ namespace Org.BouncyCastle.Utilities.Encoders if ((b1 | b2 | b3 | b4) >= 0x80) throw new IOException("invalid characters encountered in base64 data"); - outStream.WriteByte((byte)((b1 << 2) | (b2 >> 4))); - outStream.WriteByte((byte)((b2 << 4) | (b3 >> 2))); - outStream.WriteByte((byte)((b3 << 6) | b4)); + outBuffer[bufOff++] = (byte)((b1 << 2) | (b2 >> 4)); + outBuffer[bufOff++] = (byte)((b2 << 4) | (b3 >> 2)); + outBuffer[bufOff++] = (byte)((b3 << 6) | b4); length += 3; + if (bufOff == outBuffer.Length) + { + outStream.Write(outBuffer, 0, bufOff); + bufOff = 0; + } + i = nextI(data, i, finish); } - length += decodeLastBlock(outStream, data[end - 4], data[end - 3], data[end - 2], data[end - 1]); + if (bufOff > 0) + { + outStream.Write(outBuffer, 0, bufOff); + } + + int e0 = nextI(data, i, end); + int e1 = nextI(data, e0 + 1, end); + int e2 = nextI(data, e1 + 1, end); + int e3 = nextI(data, e2 + 1, end); + + length += decodeLastBlock(outStream, data[e0], data[e1], data[e2], data[e3]); return length; } diff --git a/crypto/src/util/encoders/HexEncoder.cs b/crypto/src/util/encoders/HexEncoder.cs index 950bc8477..090c9d7e3 100644 --- a/crypto/src/util/encoders/HexEncoder.cs +++ b/crypto/src/util/encoders/HexEncoder.cs @@ -39,26 +39,40 @@ namespace Org.BouncyCastle.Utilities.Encoders InitialiseDecodingTable(); } + public int Encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) + { + int inPos = inOff; + int inEnd = inOff + inLen; + int outPos = outOff; + + while (inPos < inEnd) + { + uint b = inBuf[inPos++]; + + outBuf[outPos++] = encodingTable[b >> 4]; + outBuf[outPos++] = encodingTable[b & 0xF]; + } + + return outPos - outOff; + } + /** * encode the input data producing a Hex output stream. * * @return the number of bytes produced. */ - public int Encode( - byte[] data, - int off, - int length, - Stream outStream) + public int Encode(byte[] buf, int off, int len, Stream outStream) { - for (int i = off; i < (off + length); i++) + byte[] tmp = new byte[72]; + while (len > 0) { - int v = data[i]; - - outStream.WriteByte(encodingTable[v >> 4]); - outStream.WriteByte(encodingTable[v & 0xf]); + int inLen = System.Math.Min(36, len); + int outLen = Encode(buf, off, inLen, tmp, 0); + outStream.Write(tmp, 0, outLen); + off += inLen; + len -= inLen; } - - return length * 2; + return len * 2; } private static bool Ignore(char c) @@ -80,6 +94,8 @@ namespace Org.BouncyCastle.Utilities.Encoders { byte b1, b2; int outLen = 0; + byte[] buf = new byte[36]; + int bufOff = 0; int end = off + length; while (end > off) @@ -112,11 +128,22 @@ namespace Org.BouncyCastle.Utilities.Encoders if ((b1 | b2) >= 0x80) throw new IOException("invalid characters encountered in Hex data"); - outStream.WriteByte((byte)((b1 << 4) | b2)); + buf[bufOff++] = (byte)((b1 << 4) | b2); + + if (bufOff == buf.Length) + { + outStream.Write(buf, 0, bufOff); + bufOff = 0; + } outLen++; } + if (bufOff > 0) + { + outStream.Write(buf, 0, bufOff); + } + return outLen; } @@ -130,10 +157,11 @@ namespace Org.BouncyCastle.Utilities.Encoders string data, Stream outStream) { - byte b1, b2; - int length = 0; - - int end = data.Length; + byte b1, b2; + int length = 0; + byte[] buf = new byte[36]; + int bufOff = 0; + int end = data.Length; while (end > 0) { @@ -165,11 +193,22 @@ namespace Org.BouncyCastle.Utilities.Encoders if ((b1 | b2) >= 0x80) throw new IOException("invalid characters encountered in Hex data"); - outStream.WriteByte((byte)((b1 << 4) | b2)); + buf[bufOff++] = (byte)((b1 << 4) | b2); + + if (bufOff == buf.Length) + { + outStream.Write(buf, 0, bufOff); + bufOff = 0; + } length++; } + if (bufOff > 0) + { + outStream.Write(buf, 0, bufOff); + } + return length; } |