public override bool Verify(ArraySegment <byte> signature, ArraySegment <byte> message, ArraySegment <byte> key) { if (signature.Array == null) { throw new ArgumentNullException("signature.Array"); } if (message.Array == null) { throw new ArgumentNullException("message.Array"); } if (key.Array == null) { throw new ArgumentNullException("key.Array"); } if (key.Count != 32) { throw new ArgumentException("Invalid key size", "key"); } if (signature.Count != 16) { throw new ArgumentException("Invalid signature size", "signature"); } var tempBytes = new byte[16];//todo: remove allocation ByteIntegerConverter.Array8LoadLittleEndian32(out Array8 <uint> internalKey, key.Array, key.Offset); Poly1305Donna.poly1305_auth(tempBytes, 0, message.Array, message.Offset, message.Count, ref internalKey); return(CryptoBytes.ConstantTimeEquals(new ArraySegment <byte>(tempBytes), signature)); }
public override bool Verify(byte[] signature, byte[] message, byte[] key) { if (signature == null) { throw new ArgumentNullException("signature"); } if (message == null) { throw new ArgumentNullException("message"); } if (key == null) { throw new ArgumentNullException("key"); } if (signature.Length != 16) { throw new ArgumentException("Invalid signature size", "signature"); } if (key.Length != 32) { throw new ArgumentException("Invalid key size", "key"); } var tempBytes = new byte[16];//todo: remove allocation ByteIntegerConverter.Array8LoadLittleEndian32(out Array8 <uint> internalKey, key, 0); Poly1305Donna.poly1305_auth(tempBytes, 0, message, 0, message.Length, ref internalKey); return(CryptoBytes.ConstantTimeEquals(tempBytes, signature)); }
public override void Sign(ArraySegment <byte> signature, ArraySegment <byte> message, ArraySegment <byte> key) { if (signature.Array == null) { throw new ArgumentNullException("signature.Array"); } if (message.Array == null) { throw new ArgumentNullException("message.Array"); } if (key.Array == null) { throw new ArgumentNullException("key.Array"); } if (key.Count != 32) { throw new ArgumentException("Invalid key size", "key"); } if (signature.Count != 16) { throw new ArgumentException("Invalid signature size", "signature"); } ByteIntegerConverter.Array8LoadLittleEndian32(out var internalKey, key.Array, key.Offset); Poly1305Donna.poly1305_auth(signature.Array, signature.Offset, message.Array, message.Offset, message.Count, ref internalKey); }
private static void EncryptInternal(byte[] ciphertext, int ciphertextOffset, byte[] message, int messageOffset, int messageLength, byte[] key, int keyOffset, byte[] nonce, int nonceOffset) { Array16 <UInt32> internalKey; PrepareInternalKey(out internalKey, key, keyOffset, nonce, nonceOffset); Array16 <UInt32> temp; var tempBytes = new byte[64];//todo: remove allocation Array8 <UInt32> poly1305Key; // first iteration { SalsaCore.Salsa(out temp, ref internalKey, 20); //first half is for Poly1305 poly1305Key.x0 = temp.x0; poly1305Key.x1 = temp.x1; poly1305Key.x2 = temp.x2; poly1305Key.x3 = temp.x3; poly1305Key.x4 = temp.x4; poly1305Key.x5 = temp.x5; poly1305Key.x6 = temp.x6; poly1305Key.x7 = temp.x7; // second half for the message ByteIntegerConverter.StoreLittleEndian32(tempBytes, 0, temp.x8); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 4, temp.x9); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 8, temp.x10); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 12, temp.x11); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 16, temp.x12); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 20, temp.x13); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 24, temp.x14); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 28, temp.x15); int count = Math.Min(32, messageLength); for (int i = 0; i < count; i++) { ciphertext[16 + ciphertextOffset + i] = (byte)(message[messageOffset + i] ^ tempBytes[i]); } } // later iterations int blockOffset = 32; while (blockOffset < messageLength) { internalKey.x8++; SalsaCore.Salsa(out temp, ref internalKey, 20); ByteIntegerConverter.Array16StoreLittleEndian32(tempBytes, 0, ref temp); int count = Math.Min(64, messageLength - blockOffset); for (int i = 0; i < count; i++) { ciphertext[16 + ciphertextOffset + blockOffset + i] = (byte)(message[messageOffset + blockOffset + i] ^ tempBytes[i]); } blockOffset += 64; } // compute MAC Poly1305Donna.poly1305_auth(ciphertext, ciphertextOffset, ciphertext, ciphertextOffset + 16, messageLength, ref poly1305Key); }
public override byte[] Sign(byte[] message, byte[] key) { if (message == null) { throw new ArgumentNullException("message"); } if (key == null) { throw new ArgumentNullException("key"); } if (key.Length != 32) { throw new ArgumentException("Invalid key size", "key"); } var result = new byte[16]; ByteIntegerConverter.Array8LoadLittleEndian32(out var internalKey, key, 0); Poly1305Donna.poly1305_auth(result, 0, message, 0, message.Length, ref internalKey); return(result); }
private static bool DecryptInternal(byte[] plaintext, int plaintextOffset, byte[] ciphertext, int ciphertextOffset, int ciphertextLength, byte[] key, int keyOffset, byte[] nonce, int nonceOffset) { int plaintextLength = ciphertextLength - MacSizeInBytes; Array16 <uint> internalKey; PrepareInternalKey(out internalKey, key, keyOffset, nonce, nonceOffset); Array16 <uint> temp; byte[] tempBytes = new byte[64]; //todo: remove allocation // first iteration { SalsaCore.HSalsa(out temp, ref internalKey, 20); //first half is for Poly1305 Array8 <uint> poly1305Key; poly1305Key.x0 = temp.x0; poly1305Key.x1 = temp.x1; poly1305Key.x2 = temp.x2; poly1305Key.x3 = temp.x3; poly1305Key.x4 = temp.x4; poly1305Key.x5 = temp.x5; poly1305Key.x6 = temp.x6; poly1305Key.x7 = temp.x7; // compute MAC Poly1305Donna.poly1305_auth(tempBytes, 0, ciphertext, ciphertextOffset + 16, plaintextLength, ref poly1305Key); if (!CryptoBytes.ConstantTimeEquals(tempBytes, 0, ciphertext, ciphertextOffset, MacSizeInBytes)) { Array.Clear(plaintext, plaintextOffset, plaintextLength); return(false); } // rest for the message ByteIntegerConverter.StoreLittleEndian32(tempBytes, 0, temp.x8); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 4, temp.x9); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 8, temp.x10); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 12, temp.x11); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 16, temp.x12); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 20, temp.x13); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 24, temp.x14); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 28, temp.x15); int count = Math.Min(32, plaintextLength); for (int i = 0; i < count; i++) { plaintext[plaintextOffset + i] = (byte)(ciphertext[MacSizeInBytes + ciphertextOffset + i] ^ tempBytes[i]); } } // later iterations int blockOffset = 32; while (blockOffset < plaintextLength) { internalKey.x8++; SalsaCore.HSalsa(out temp, ref internalKey, 20); ByteIntegerConverter.Array16StoreLittleEndian32(tempBytes, 0, ref temp); int count = Math.Min(64, plaintextLength - blockOffset); for (int i = 0; i < count; i++) { plaintext[plaintextOffset + blockOffset + i] = (byte)(ciphertext[16 + ciphertextOffset + blockOffset + i] ^ tempBytes[i]); } blockOffset += 64; } return(true); }
private static bool DecryptInternal(byte[] plaintext, int plaintextOffset, byte[] ciphertext, int ciphertextOffset, int ciphertextLength, byte[] key, int keyOffset, byte[] nonce, int nonceOffset) { int plaintextLength = ciphertextLength - MacSizeInBytes; Array16\\ internalKey; PrepareInternalKey(out internalKey, key, keyOffset, nonce, nonceOffset); Array16\\ temp; var tempBytes = new byte[64];//todo: remove allocation // first iteration { SalsaCore.Salsa(out temp, ref internalKey, 20); //first half is for Poly1305 Array8\\ poly1305Key; poly1305Key.x0 = temp.x0; poly1305Key.x1 = temp.x1; poly1305Key.x2 = temp.x2; poly1305Key.x3 = temp.x3; poly1305Key.x4 = temp.x4; poly1305Key.x5 = temp.x5; poly1305Key.x6 = temp.x6; poly1305Key.x7 = temp.x7; // compute MAC Poly1305Donna.poly1305_auth(tempBytes, 0, ciphertext, ciphertextOffset + 16, plaintextLength, ref poly1305Key); if (!CryptoBytes.ConstantTimeEquals(tempBytes, 0, ciphertext, ciphertextOffset, MacSizeInBytes)) { Array.Clear(plaintext, plaintextOffset, plaintextLength); return false; } // rest for the message ByteIntegerConverter.StoreLittleEndian32(tempBytes, 0, temp.x8); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 4, temp.x9); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 8, temp.x10); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 12, temp.x11); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 16, temp.x12); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 20, temp.x13); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 24, temp.x14); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 28, temp.x15); int count = Math.Min(32, plaintextLength); for (int i = 0; i \\ internalKey; PrepareInternalKey(out internalKey, key, keyOffset, nonce, nonceOffset); Array16\\ temp; var tempBytes = new byte[64];//todo: remove allocation Array8\\ poly1305Key; // first iteration { SalsaCore.Salsa(out temp, ref internalKey, 20); //first half is for Poly1305 poly1305Key.x0 = temp.x0; poly1305Key.x1 = temp.x1; poly1305Key.x2 = temp.x2; poly1305Key.x3 = temp.x3; poly1305Key.x4 = temp.x4; poly1305Key.x5 = temp.x5; poly1305Key.x6 = temp.x6; poly1305Key.x7 = temp.x7; // second half for the message ByteIntegerConverter.StoreLittleEndian32(tempBytes, 0, temp.x8); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 4, temp.x9); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 8, temp.x10); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 12, temp.x11); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 16, temp.x12); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 20, temp.x13); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 24, temp.x14); ByteIntegerConverter.StoreLittleEndian32(tempBytes, 28, temp.x15); int count = Math.Min(32, messageLength); for (int i = 0; i \