public void Encrypt(BufRef dest, BufLen data, bool zeropad) { if (data == null || data.Length > 222) { throw new InvalidParameterException("ElGamal data length can max be 222 bytes!"); } var hashbuf = new BufRefLen(new byte[255]); hashbuf.Write8(0xFF); hashbuf.Write(I2PHashSHA256.GetHash(data)); hashbuf.Write(data); hashbuf.Reset(); var b = b1.Multiply(new BigInteger(1, hashbuf.ToByteArray())).Mod(I2PConstants.ElGamalP); if (zeropad) { dest.Write8(0); dest.Write(a.ToByteArray(256)); dest.Write8(0); dest.Write(b.ToByteArray(256)); } else { dest.Write(a.ToByteArray(256)); dest.Write(b.ToByteArray(256)); } }
public static bool Equal(BufRefLen b1, BufRefLen b2) { if (Object.ReferenceEquals(b1, null) && Object.ReferenceEquals(b2, null)) { return(true); } if (Object.ReferenceEquals(b1, null) || Object.ReferenceEquals(b2, null)) { return(false); } if (Object.ReferenceEquals(b1, b2)) { return(true); } if (b1.Length != b2.Length) { return(false); } for (int i = 0; i < b1.Length; ++i) { if (b1.BaseArray[b1.BaseArrayOffset + i] != b2.BaseArray[b2.BaseArrayOffset + i]) { return(false); } } return(true); }
public static void Encrypt(BufRef dest, BufLen data, I2PPublicKey key, bool zeropad) { if (data == null || data.Length > ClearTextLength) { throw new InvalidParameterException($"ElGamal data must be {ClearTextLength} bytes or less!"); } var k = new BigInteger(I2PConstants.ElGamalFullExponentBits, Rnd); var a = I2PConstants.ElGamalG.ModPow(k, I2PConstants.ElGamalP); var b1 = key.ToBigInteger().ModPow(k, I2PConstants.ElGamalP); var start = new BufLen(new byte[EGBlockLength]); var writer = new BufRefLen(start, 1); start[0] = 0xFF; writer.Write(I2PHashSHA256.GetHash(data)); writer.Write(data); var egblock = new BufLen(start, 0, writer - start); var egint = egblock.ToBigInteger(); var b = b1.Multiply(egint).Mod(I2PConstants.ElGamalP); var targetlen = zeropad ? EncryptedPaddedLength / 2 : EncryptedShortLength / 2; WriteToDest(dest, a, targetlen); WriteToDest(dest, b, targetlen); }
bool IEquatable <BufRefLen> .Equals(BufRefLen other) { if (Object.ReferenceEquals(other, null)) { return(false); } return(Equal(this, other)); }
public void Poke(BufRefLen src, int offset, int maxlen) { var len = Math.Min(maxlen, src.Length); PreWriteCheck(offset + len); Array.Copy(src.Data, src.Position, Data, Position + offset, len); }
bool IEquatable <BufRefLen> .Equals(BufRefLen other) { if (other is null) { return(false); } return(Equal(this, other)); }
public virtual int Write(BufRefLen src) { PreWriteCheck(src.Length); Array.Copy(src.BaseArray, src.BaseArrayOffset, BaseArray, BaseArrayOffset, src.Length); Seek(src.Length); src.Seek(src.Length); return(src.Length); }
public BufRefLen ReadBufRefLen(int length) { PreReadCheck(length); var result = new BufRefLen(this, 0, length); Seek(length); return(result); }
public static string Encode(BufLen data) { var result = new StringBuilder(); var reader = new BufRefLen(data); byte v1, v2; for (int i = 0; i < data.Length / 3; ++i) { v1 = reader.Read8(); v2 = (byte)((v1 << 4) & 0x30); v1 >>= 2; result.Append(Domain[v1]); v1 = reader.Read8(); v2 |= (byte)(v1 >> 4); result.Append(Domain[v2]); v1 = (byte)((v1 & 0x0f) << 2); v2 = reader.Read8(); v1 |= (byte)(v2 >> 6); result.Append(Domain[v1]); v2 &= 0x3f; result.Append(Domain[v2]); } switch (data.Length % 3) { case 1: v1 = reader.Read8(); v2 = (byte)((v1 << 4) & 0x3f); v1 >>= 2; result.Append(Domain[v1]); result.Append(Domain[v2]); result.Append("=="); break; case 2: v1 = reader.Read8(); v2 = (byte)((v1 << 4) & 0x3f); v1 >>= 2; result.Append(Domain[v1]); v1 = reader.Read8(); v2 |= (byte)(v1 >> 4); result.Append(Domain[v2]); v1 = (byte)((v1 & 0x0f) << 2); result.Append(Domain[v1]); result.Append("="); break; } return(result.ToString()); }
public static BufLen Generate(IEnumerable <BufLen> msg, BufLen key, BufLen dest) { if (key.Length != 32) { throw new NotImplementedException("Only keys of 32 bits supported"); } var m5 = new MD5Digest(); var hash = new byte[m5.GetDigestSize()]; var buf = new byte[BLOCK_LENGTH]; var writer = new BufRefLen(buf); writer.Write64(key.Peek64(0) ^ IPAD); writer.Write64(key.Peek64(1 * 8) ^ IPAD); writer.Write64(key.Peek64(2 * 8) ^ IPAD); writer.Write64(key.Peek64(3 * 8) ^ IPAD); m5.BlockUpdate(buf, 0, BLOCK_LENGTH); m5.BlockUpdate(IPADBUF, 0, IPADBUF.Length); foreach (var one in msg) { m5.BlockUpdate(one.BaseArray, one.BaseArrayOffset, one.Length); } m5.DoFinal(hash, 0); writer = new BufRefLen(buf); writer.Write64(key.Peek64(0) ^ OPAD); writer.Write64(key.Peek64(1 * 8) ^ OPAD); writer.Write64(key.Peek64(2 * 8) ^ OPAD); writer.Write64(key.Peek64(3 * 8) ^ OPAD); m5.Reset(); m5.BlockUpdate(buf, 0, BLOCK_LENGTH); m5.BlockUpdate(OPADBUF, 0, OPADBUF.Length); m5.BlockUpdate(hash, 0, hash.Length); m5.BlockUpdate(NULLPAD, 0, NULLPAD.Length); if (dest.Length < m5.GetDigestSize()) { throw new OverflowException("Not enough dest buffer size for I2PHMACMD5Digest.Generate()!"); } m5.DoFinal(dest.BaseArray, dest.BaseArrayOffset); return(dest); }
public static byte[] BCGZipDecompress(BufLen buf) { var reader = new BufRefLen(buf); using (var ms = new MemoryStream()) { // Skip gzip header var gzheader = reader.ReadBufLen(10); var flag = gzheader.Peek8(3); if ((flag & 0x04) != 0) { reader.Seek(reader.Read16()); // "Extra" } if ((flag & 0x08) != 0) { while (reader.Read8() != 0) { ; // "Name" } } if ((flag & 0x10) != 0) { while (reader.Read8() != 0) { ; // "Comment" } } if ((flag & 0x02) != 0) { reader.Read16(); // "CRC16" } ms.Write(reader.BaseArray, reader.BaseArrayOffset, reader.Length); ms.Position = 0; using (var gzs = new ZInputStream(ms, true)) { var gzdata = StreamUtils.Read(gzs); return(gzdata); } } }
public static BufLen Decrypt(BufLen data, I2PPrivateKey pkey, bool zeropad) { if (data == null || (zeropad && data.Length != 514)) { throw new ArgumentException("ElGamal padded data to decrypt must be exactly 514 bytes!"); } if (!zeropad && data.Length != 512) { throw new ArgumentException("ElGamal data to decrypt must be exactly 512 bytes!"); } var x = I2PConstants.ElGamalP.Subtract(pkey.ToBigInteger()).Subtract(BigInteger.One); BigInteger a, b; var reader = new BufRefLen(data); if (zeropad) { reader.Seek(1); a = reader.ReadBigInteger(256); reader.Seek(1); b = reader.ReadBigInteger(256); } else { a = reader.ReadBigInteger(256); b = reader.ReadBigInteger(256); } var m2 = b.Multiply(a.ModPow(x, I2PConstants.ElGamalP)); var m1 = m2.Mod(I2PConstants.ElGamalP); var m = m1.ToByteArray(255); var hash = I2PHashSHA256.GetHash(m, 33, 222); if (!BufUtils.Equal(m, 1, hash, 0, 32)) { throw new HashCheckFailException(); } return(new BufLen(m, 33, 222)); }
public static int ComputeHash(BufRefLen data) { unchecked { const int p = 16777619; int hash = (int)2166136261; var end = data.BaseArrayOffset + data.Length; for (int i = data.BaseArrayOffset; i < end; ++i) { hash = (hash ^ data.BaseArray[i]) * p; } hash += hash << 13; hash ^= hash >> 7; hash += hash << 3; hash ^= hash >> 17; hash += hash << 5; return(hash); } }
public static int Compare(BufRefLen b1, BufRefLen b2) { if (Object.ReferenceEquals(b1, null) && Object.ReferenceEquals(b2, null)) { return(0); } if (Object.ReferenceEquals(b1, null)) { return(-1); } if (Object.ReferenceEquals(b2, null)) { return(1); } if (Object.ReferenceEquals(b1, b2)) { return(0); } for (int i = 0; i < b1.Length; ++i) { if (i >= b2.Length) { return(1); } var c = b1.BaseArray[b1.BaseArrayOffset + i] - b2.BaseArray[b2.BaseArrayOffset + i]; if (c != 0) { return(Math.Sign(c)); } } if (b2.Length > b1.Length) { return(-1); } return(0); }
public static BufLen Decrypt(BufLen data, I2PPrivateKey pkey, bool zeropad) { if (data == null || zeropad && data.Length != EncryptedPaddedLength) { throw new ArgumentException($"ElGamal padded data to decrypt must be exactly {EncryptedPaddedLength} bytes!"); } if (!zeropad && data.Length != EncryptedShortLength) { throw new ArgumentException($"ElGamal data to decrypt must be exactly {EncryptedShortLength} bytes!"); } var x = I2PConstants.ElGamalPMinusOne.Subtract(pkey.ToBigInteger()); var reader = new BufRefLen(data); var readlen = zeropad ? EncryptedPaddedLength / 2 : EncryptedShortLength / 2; var a = reader.ReadBigInteger(readlen); var b = reader.ReadBigInteger(readlen); var m2 = b.Multiply(a.ModPow(x, I2PConstants.ElGamalP)); var m1 = m2.Mod(I2PConstants.ElGamalP); var m = m1.ToByteArrayUnsigned(); var payload = new BufLen(m, 33, ClearTextLength); var hash = I2PHashSHA256.GetHash(payload); if (!BufUtils.Equal(m, 1, hash, 0, 32)) { throw new HashCheckFailException(); } return(payload); }
public static BufLen BCGZipDecompressNew(BufLen buf) { var reader = new BufRefLen(buf); // Skip gzip header var gzheader = reader.ReadBufLen(10); var flag = gzheader.Peek8(3); if ((flag & 0x04) != 0) { reader.Seek(reader.Read16()); // "Extra" } if ((flag & 0x08) != 0) { while (reader.Read8() != 0) { ; // "Name" } } if ((flag & 0x10) != 0) { while (reader.Read8() != 0) { ; // "Comment" } } if ((flag & 0x02) != 0) { reader.Read16(); // "CRC16" } var z = new ZStream(); z.inflateInit(true); var dest = new byte[buf.Length * 2]; var destix = 0; z.next_in_index = reader.BaseArrayOffset; z.next_in = reader.BaseArray; z.avail_in = reader.Length - 8; bigger_dest: z.next_out = dest; z.next_out_index = destix; z.avail_out = dest.Length - destix; var err = z.inflate(JZlib.Z_FINISH); if (err != JZlib.Z_BUF_ERROR && err != JZlib.Z_OK && err != JZlib.Z_STREAM_END) { throw new IOException("inflating: " + z.msg); } if (z.avail_out == 0) { var newdest = new byte[dest.Length * 2]; Array.Copy(dest, newdest, dest.Length); destix = dest.Length; dest = newdest; goto bigger_dest; } var result = new BufLen(dest, 0, dest.Length - z.avail_out); z.inflateEnd(); return(result); }
int IComparable <BufRefLen> .CompareTo(BufRefLen other) { return(Compare(this, other)); }
public BufLen(BufRefLen src, int offset, int len) : base(src, offset) { LengthDef = Math.Min(len, src.Length - offset); }
public static void Randomize(this BufRefLen buf) { Rnd.NextBytes(buf.BaseArray, buf.BaseArrayOffset, buf.Length); }
public BufLen(BufRefLen src, int offset) : base(src, offset) { LengthDef = src.Length - offset; }
public BufLen(BufRefLen src) : base(src) { LengthDef = src.Length; }
public static byte[] Decode(string data) { if (data.Length < 4 || data.Length % 4 != 0) { throw new FormatException("FreenetBase64 string needs to be padded to 4 byte align!"); } var size = 3 * (data.Length / 4); if (data[data.Length - 1] == '=') { --size; } if (data[data.Length - 2] == '=') { --size; } if (data[data.Length - 3] == '=') { --size; } var result = new byte[size]; if (Codomain == null) { Codomain = new int[256]; for (int i = 0; i < 256; ++i) { Codomain[i] = -1; } for (int i = 0; i < 64; ++i) { Codomain[(byte)Domain[i]] = i; } Codomain[(byte)'='] = 0; } byte v1, v2; var reader = data.GetEnumerator(); reader.MoveNext(); var writer = new BufRefLen(result); for (int i = 0; i < data.Length / 4; ++i) { v1 = Lookup(reader); v2 = Lookup(reader); v1 <<= 2; v1 |= (byte)(v2 >> 4); writer.Write8(v1); if (writer.Length == 0) { break; } v2 <<= 4; v1 = Lookup(reader); v2 |= (byte)(v1 >> 2); writer.Write8(v2); if (writer.Length == 0) { break; } v2 = Lookup(reader); v2 |= (byte)(v1 << 6); writer.Write8(v2); if (writer.Length == 0) { break; } } return(result); }
public BufRefLen(BufRefLen src, int offset, int len) : base(src, offset) { LengthDef = Math.Min(len, src.BaseArray.Length - src.BaseArrayOffset - offset); }
public void Poke(BufRefLen src, int offset) { PreWriteCheck(offset + src.Length); Array.Copy(src.Data, src.Position, Data, Position + offset, src.Length); }