public EcKeyPair GetSenderRatchetKeyPair() { IEcPublicKey publicKey = GetSenderRatchetKey(); IEcPrivateKey privateKey = Curve.DecodePrivatePoint(_sessionStructure.SenderChain .SenderRatchetKeyPrivate .ToByteArray()); return(new EcKeyPair(publicKey, privateKey)); }
public IdentityKeyPair GetPendingKeyExchangeIdentityKey() { IdentityKey publicKey = new IdentityKey(_sessionStructure.PendingKeyExchange .LocalIdentityKey.ToByteArray(), 0); IEcPrivateKey privateKey = Curve.DecodePrivatePoint(_sessionStructure.PendingKeyExchange .LocalIdentityKeyPrivate .ToByteArray()); return(new IdentityKeyPair(publicKey, privateKey)); }
public EcKeyPair GetPendingKeyExchangeRatchetKey() { IEcPublicKey publicKey = Curve.DecodePoint(_sessionStructure.PendingKeyExchange .LocalRatchetKey.ToByteArray(), 0); IEcPrivateKey privateKey = Curve.DecodePrivatePoint(_sessionStructure.PendingKeyExchange .LocalRatchetKeyPrivate .ToByteArray()); return(new EcKeyPair(publicKey, privateKey)); }
private byte[] GetSignature(IEcPrivateKey signatureKey, byte[] serialized) { try { return(Curve.CalculateSignature(signatureKey, serialized)); } catch (InvalidKeyException e) { throw new Exception(e.Message); } }
public static byte[] CalculateSignature(IEcPrivateKey signingKey, byte[] message) { if (signingKey.GetKeyType() == DjbType) { return(Curve25519.GetInstance(Curve25519ProviderType.Best) .CalculateSignature(((DjbEcPrivateKey)signingKey).GetPrivateKey(), message)); } else { throw new InvalidKeyException("Unknown type: " + signingKey.GetKeyType()); } }
public IdentityKeyPair(byte[] serialized) { try { StorageProtos.IdentityKeyPairStructure structure = StorageProtos.IdentityKeyPairStructure.ParseFrom(serialized); _publicKey = new IdentityKey(structure.PublicKey.ToByteArray(), 0); _privateKey = Curve.DecodePrivatePoint(structure.PrivateKey.ToByteArray()); } catch (InvalidProtocolBufferException e) { throw new InvalidKeyException(e); } }
public EcKeyPair GetKeyPair() { try { IEcPublicKey publicKey = Curve.DecodePoint(_structure.PublicKey.ToByteArray(), 0); IEcPrivateKey privateKey = Curve.DecodePrivatePoint(_structure.PrivateKey.ToByteArray()); return(new EcKeyPair(publicKey, privateKey)); } catch (InvalidKeyException e) { throw new Exception(e.Message); } }
public SenderKeyMessage(uint keyId, uint iteration, byte[] ciphertext, IEcPrivateKey signatureKey) { byte[] version = { ByteUtil.IntsToByteHighAndLow((int)CurrentVersion, (int)CurrentVersion) }; byte[] message = WhisperProtos.SenderKeyMessage.CreateBuilder() .SetId(keyId) .SetIteration(iteration) .SetCiphertext(ByteString.CopyFrom(ciphertext)) .Build().ToByteArray(); byte[] signature = GetSignature(signatureKey, ByteUtil.Combine(version, message)); _serialized = ByteUtil.Combine(version, message, signature); _messageVersion = CurrentVersion; _keyId = keyId; _iteration = iteration; _ciphertext = ciphertext; }
public static byte[] CalculateAgreement(IEcPublicKey publicKey, IEcPrivateKey privateKey) { if (publicKey.GetKeyType() != privateKey.GetKeyType()) { throw new InvalidKeyException("Public and private keys must be of the same type!"); } if (publicKey.GetKeyType() == DjbType) { return(Curve25519.GetInstance(Curve25519ProviderType.Best) .CalculateAgreement(((DjbEcPublicKey)publicKey).GetPublicKey(), ((DjbEcPrivateKey)privateKey).GetPrivateKey())); } else { throw new InvalidKeyException("Unknown type: " + publicKey.GetKeyType()); } }
public SenderKeyMessage(uint keyId, uint iteration, byte[] ciphertext, IEcPrivateKey signatureKey) { byte[] version = { ByteUtil.IntsToByteHighAndLow((int)CurrentVersion, (int)CurrentVersion) }; byte[] message = new SenderKeyMessage { Id = keyId, Iteration = iteration, Ciphertext = ByteString.CopyFrom(ciphertext), }.ToByteArray(); byte[] signature = GetSignature(signatureKey, ByteUtil.Combine(version, message)); _serialized = ByteUtil.Combine(version, message, signature); _messageVersion = CurrentVersion; _keyId = keyId; _iteration = iteration; _ciphertext = ciphertext; }
public IdentityKeyPair(IdentityKey publicKey, IEcPrivateKey privateKey) { _publicKey = publicKey; _privateKey = privateKey; }
public void TestRootKeyDerivationV2() { byte[] rootKeySeed = { 0x7b, 0xa6, 0xde, 0xbc, 0x2b, 0xc1, 0xbb, 0xf9, 0x1a, 0xbb, 0xc1, 0x36, 0x74, 0x04, 0x17, 0x6c, 0xa6, 0x23, 0x09, 0x5b, 0x7e, 0xc6, 0x6b, 0x45, 0xf6, 0x02, 0xd9, 0x35, 0x38, 0x94, 0x2d, 0xcc }; byte[] alicePublic = { 0x05, 0xee, 0x4f, 0xa6, 0xcd, 0xc0, 0x30, 0xdf, 0x49, 0xec, 0xd0, 0xba, 0x6c, 0xfc, 0xff, 0xb2, 0x33, 0xd3, 0x65, 0xa2, 0x7f, 0xad, 0xbe, 0xff, 0x77, 0xe9, 0x63, 0xfc, 0xb1, 0x62, 0x22, 0xe1, 0x3a }; byte[] alicePrivate = { 0x21, 0x68, 0x22, 0xec, 0x67, 0xeb, 0x38, 0x04, 0x9e, 0xba, 0xe7, 0xb9, 0x39, 0xba, 0xea, 0xeb, 0xb1, 0x51, 0xbb, 0xb3, 0x2d, 0xb8, 0x0f, 0xd3, 0x89, 0x24, 0x5a, 0xc3, 0x7a, 0x94, 0x8e, 0x50 }; byte[] bobPublic = { 0x05, 0xab, 0xb8, 0xeb, 0x29, 0xcc, 0x80, 0xb4, 0x71, 0x09, 0xa2, 0x26, 0x5a, 0xbe, 0x97, 0x98, 0x48, 0x54, 0x06, 0xe3, 0x2d, 0xa2, 0x68, 0x93, 0x4a, 0x95, 0x55, 0xe8, 0x47, 0x57, 0x70, 0x8a, 0x30 }; byte[] nextRoot = { 0xb1, 0x14, 0xf5, 0xde, 0x28, 0x01, 0x19, 0x85, 0xe6, 0xeb, 0xa2, 0x5d, 0x50, 0xe7, 0xec, 0x41, 0xa9, 0xb0, 0x2f, 0x56, 0x93, 0xc5, 0xc7, 0x88, 0xa6, 0x3a, 0x06, 0xd2, 0x12, 0xa2, 0xf7, 0x31 }; byte[] nextChain = { 0x9d, 0x7d, 0x24, 0x69, 0xbc, 0x9a, 0xe5, 0x3e, 0xe9, 0x80, 0x5a, 0xa3, 0x26, 0x4d, 0x24, 0x99, 0xa3, 0xac, 0xe8, 0x0f, 0x4c, 0xca, 0xe2, 0xda, 0x13, 0x43, 0x0c, 0x5c, 0x55, 0xb5, 0xca, 0x5f }; IEcPublicKey alicePublicKey = Curve.DecodePoint(alicePublic, 0); IEcPrivateKey alicePrivateKey = Curve.DecodePrivatePoint(alicePrivate); EcKeyPair aliceKeyPair = new EcKeyPair(alicePublicKey, alicePrivateKey); IEcPublicKey bobPublicKey = Curve.DecodePoint(bobPublic, 0); RootKey rootKey = new RootKey(Hkdf.CreateFor(2), rootKeySeed); Pair <RootKey, ChainKey> rootKeyChainKeyPair = rootKey.CreateChain(bobPublicKey, aliceKeyPair); RootKey nextRootKey = rootKeyChainKeyPair.First(); ChainKey nextChainKey = rootKeyChainKeyPair.Second(); CollectionAssert.AreEqual(rootKey.GetKeyBytes(), rootKeySeed); CollectionAssert.AreEqual(nextRootKey.GetKeyBytes(), nextRoot); CollectionAssert.AreEqual(nextChainKey.GetKey(), nextChain); }
public EcKeyPair(IEcPublicKey publicKey, IEcPrivateKey privateKey) { _publicKey = publicKey; _privateKey = privateKey; }
public void TestAgreement() { byte[] alicePublic = { 0x05, 0x1b, 0xb7, 0x59, 0x66, 0xf2, 0xe9, 0x3a, 0x36, 0x91, 0xdf, 0xff, 0x94, 0x2b, 0xb2, 0xa4, 0x66, 0xa1, 0xc0, 0x8b, 0x8d, 0x78, 0xca, 0x3f, 0x4d, 0x6d, 0xf8, 0xb8, 0xbf, 0xa2, 0xe4, 0xee, 0x28 }; byte[] alicePrivate = { 0xc8, 0x06, 0x43, 0x9d, 0xc9, 0xd2, 0xc4, 0x76, 0xff, 0xed, 0x8f, 0x25, 0x80, 0xc0, 0x88, 0x8d, 0x58, 0xab, 0x40, 0x6b, 0xf7, 0xae, 0x36, 0x98, 0x87, 0x90, 0x21, 0xb9, 0x6b, 0xb4, 0xbf, 0x59 }; byte[] bobPublic = { 0x05, 0x65, 0x36, 0x14, 0x99, 0x3d, 0x2b, 0x15, 0xee, 0x9e, 0x5f, 0xd3, 0xd8, 0x6c, 0xe7, 0x19, 0xef, 0x4e, 0xc1, 0xda, 0xae, 0x18, 0x86, 0xa8, 0x7b, 0x3f, 0x5f, 0xa9, 0x56, 0x5a, 0x27, 0xa2, 0x2f }; byte[] bobPrivate = { 0xb0, 0x3b, 0x34, 0xc3, 0x3a, 0x1c, 0x44, 0xf2, 0x25, 0xb6, 0x62, 0xd2, 0xbf, 0x48, 0x59, 0xb8, 0x13, 0x54, 0x11, 0xfa, 0x7b, 0x03, 0x86, 0xd4, 0x5f, 0xb7, 0x5d, 0xc5, 0xb9, 0x1b, 0x44, 0x66 }; byte[] shared = { 0x32, 0x5f, 0x23, 0x93, 0x28, 0x94, 0x1c, 0xed, 0x6e, 0x67, 0x3b, 0x86, 0xba, 0x41, 0x01, 0x74, 0x48, 0xe9, 0x9b, 0x64, 0x9a, 0x9c, 0x38, 0x06, 0xc1, 0xdd, 0x7c, 0xa4, 0xc4, 0x77, 0xe6, 0x29 }; IEcPublicKey alicePublicKey = Curve.DecodePoint(alicePublic, 0); IEcPrivateKey alicePrivateKey = Curve.DecodePrivatePoint(alicePrivate); IEcPublicKey bobPublicKey = Curve.DecodePoint(bobPublic, 0); IEcPrivateKey bobPrivateKey = Curve.DecodePrivatePoint(bobPrivate); byte[] sharedOne = Curve.CalculateAgreement(alicePublicKey, bobPrivateKey); byte[] sharedTwo = Curve.CalculateAgreement(bobPublicKey, alicePrivateKey); CollectionAssert.AreEqual(sharedOne, shared); CollectionAssert.AreEqual(sharedTwo, shared); }
public void TestSignature() { byte[] aliceIdentityPrivate = { 0xc0, 0x97, 0x24, 0x84, 0x12, 0xe5, 0x8b, 0xf0, 0x5d, 0xf4, 0x87, 0x96, 0x82, 0x05, 0x13, 0x27, 0x94, 0x17, 0x8e, 0x36, 0x76, 0x37, 0xf5, 0x81, 0x8f, 0x81, 0xe0, 0xe6, 0xce, 0x73, 0xe8, 0x65 }; byte[] aliceIdentityPublic = { 0x05, 0xab, 0x7e, 0x71, 0x7d, 0x4a, 0x16, 0x3b, 0x7d, 0x9a, 0x1d, 0x80, 0x71, 0xdf, 0xe9, 0xdc, 0xf8, 0xcd, 0xcd, 0x1c, 0xea, 0x33, 0x39, 0xb6, 0x35, 0x6b, 0xe8, 0x4d, 0x88, 0x7e, 0x32, 0x2c, 0x64 }; byte[] aliceEphemeralPublic = { 0x05, 0xed, 0xce, 0x9d, 0x9c, 0x41, 0x5c, 0xa7, 0x8c, 0xb7, 0x25, 0x2e, 0x72, 0xc2, 0xc4, 0xa5, 0x54, 0xd3, 0xeb, 0x29, 0x48, 0x5a, 0x0e, 0x1d, 0x50, 0x31, 0x18, 0xd1, 0xa8, 0x2d, 0x99, 0xfb, 0x4a }; byte[] aliceSignature = { 0x5d, 0xe8, 0x8c, 0xa9, 0xa8, 0x9b, 0x4a, 0x11, 0x5d, 0xa7, 0x91, 0x09, 0xc6, 0x7c, 0x9c, 0x74, 0x64, 0xa3, 0xe4, 0x18, 0x02, 0x74, 0xf1, 0xcb, 0x8c, 0x63, 0xc2, 0x98, 0x4e, 0x28, 0x6d, 0xfb, 0xed, 0xe8, 0x2d, 0xeb, 0x9d, 0xcd, 0x9f, 0xae, 0x0b, 0xfb, 0xb8, 0x21, 0x56, 0x9b, 0x3d, 0x90, 0x01, 0xbd, 0x81, 0x30, 0xcd, 0x11, 0xd4, 0x86, 0xce, 0xf0, 0x47, 0xbd, 0x60, 0xb8, 0x6e, 0x88 }; IEcPrivateKey alicePrivateKey = Curve.DecodePrivatePoint(aliceIdentityPrivate); IEcPublicKey alicePublicKey = Curve.DecodePoint(aliceIdentityPublic, 0); IEcPublicKey aliceEphemeral = Curve.DecodePoint(aliceEphemeralPublic, 0); if (!Curve.VerifySignature(alicePublicKey, aliceEphemeral.Serialize(), aliceSignature)) { Assert.Fail("Sig verification failed!"); } for (int i = 0; i < aliceSignature.Length; i++) { byte[] modifiedSignature = new byte[aliceSignature.Length]; System.Buffer.BlockCopy(aliceSignature, 0, modifiedSignature, 0, modifiedSignature.Length); modifiedSignature[i] ^= 0x01; if (Curve.VerifySignature(alicePublicKey, aliceEphemeral.Serialize(), modifiedSignature)) { Assert.Fail("Sig verification succeeded!"); } } }
public void TestRatchetingSessionAsBob() { byte[] bobPublic = { (byte)0x05, (byte)0x2c, (byte)0xb4, (byte)0x97, (byte)0x76, (byte)0xb8, (byte)0x77, (byte)0x02, (byte)0x05, (byte)0x74, (byte)0x5a, (byte)0x3a, (byte)0x6e, (byte)0x24, (byte)0xf5, (byte)0x79, (byte)0xcd, (byte)0xb4, (byte)0xba, (byte)0x7a, (byte)0x89, (byte)0x04, (byte)0x10, (byte)0x05, (byte)0x92, (byte)0x8e, (byte)0xbb, (byte)0xad, (byte)0xc9, (byte)0xc0, (byte)0x5a, (byte)0xd4, (byte)0x58 }; byte[] bobPrivate = { (byte)0xa1, (byte)0xca, (byte)0xb4, (byte)0x8f, (byte)0x7c, (byte)0x89, (byte)0x3f, (byte)0xaf, (byte)0xa9, (byte)0x88, (byte)0x0a, (byte)0x28, (byte)0xc3, (byte)0xb4, (byte)0x99, (byte)0x9d, (byte)0x28, (byte)0xd6, (byte)0x32, (byte)0x95, (byte)0x62, (byte)0xd2, (byte)0x7a, (byte)0x4e, (byte)0xa4, (byte)0xe2, (byte)0x2e, (byte)0x9f, (byte)0xf1, (byte)0xbd, (byte)0xd6, (byte)0x5a }; byte[] bobIdentityPublic = { (byte)0x05, (byte)0xf1, (byte)0xf4, (byte)0x38, (byte)0x74, (byte)0xf6, (byte)0x96, (byte)0x69, (byte)0x56, (byte)0xc2, (byte)0xdd, (byte)0x47, (byte)0x3f, (byte)0x8f, (byte)0xa1, (byte)0x5a, (byte)0xde, (byte)0xb7, (byte)0x1d, (byte)0x1c, (byte)0xb9, (byte)0x91, (byte)0xb2, (byte)0x34, (byte)0x16, (byte)0x92, (byte)0x32, (byte)0x4c, (byte)0xef, (byte)0xb1, (byte)0xc5, (byte)0xe6, (byte)0x26 }; byte[] bobIdentityPrivate = { (byte)0x48, (byte)0x75, (byte)0xcc, (byte)0x69, (byte)0xdd, (byte)0xf8, (byte)0xea, (byte)0x07, (byte)0x19, (byte)0xec, (byte)0x94, (byte)0x7d, (byte)0x61, (byte)0x08, (byte)0x11, (byte)0x35, (byte)0x86, (byte)0x8d, (byte)0x5f, (byte)0xd8, (byte)0x01, (byte)0xf0, (byte)0x2c, (byte)0x02, (byte)0x25, (byte)0xe5, (byte)0x16, (byte)0xdf, (byte)0x21, (byte)0x56, (byte)0x60, (byte)0x5e }; byte[] aliceBasePublic = { (byte)0x05, (byte)0x47, (byte)0x2d, (byte)0x1f, (byte)0xb1, (byte)0xa9, (byte)0x86, (byte)0x2c, (byte)0x3a, (byte)0xf6, (byte)0xbe, (byte)0xac, (byte)0xa8, (byte)0x92, (byte)0x02, (byte)0x77, (byte)0xe2, (byte)0xb2, (byte)0x6f, (byte)0x4a, (byte)0x79, (byte)0x21, (byte)0x3e, (byte)0xc7, (byte)0xc9, (byte)0x06, (byte)0xae, (byte)0xb3, (byte)0x5e, (byte)0x03, (byte)0xcf, (byte)0x89, (byte)0x50 }; byte[] aliceEphemeralPublic = { (byte)0x05, (byte)0x6c, (byte)0x3e, (byte)0x0d, (byte)0x1f, (byte)0x52, (byte)0x02, (byte)0x83, (byte)0xef, (byte)0xcc, (byte)0x55, (byte)0xfc, (byte)0xa5, (byte)0xe6, (byte)0x70, (byte)0x75, (byte)0xb9, (byte)0x04, (byte)0x00, (byte)0x7f, (byte)0x18, (byte)0x81, (byte)0xd1, (byte)0x51, (byte)0xaf, (byte)0x76, (byte)0xdf, (byte)0x18, (byte)0xc5, (byte)0x1d, (byte)0x29, (byte)0xd3, (byte)0x4b }; byte[] aliceIdentityPublic = { (byte)0x05, (byte)0xb4, (byte)0xa8, (byte)0x45, (byte)0x56, (byte)0x60, (byte)0xad, (byte)0xa6, (byte)0x5b, (byte)0x40, (byte)0x10, (byte)0x07, (byte)0xf6, (byte)0x15, (byte)0xe6, (byte)0x54, (byte)0x04, (byte)0x17, (byte)0x46, (byte)0x43, (byte)0x2e, (byte)0x33, (byte)0x39, (byte)0xc6, (byte)0x87, (byte)0x51, (byte)0x49, (byte)0xbc, (byte)0xee, (byte)0xfc, (byte)0xb4, (byte)0x2b, (byte)0x4a }; byte[] bobSignedPreKeyPublic = { (byte)0x05, (byte)0xac, (byte)0x24, (byte)0x8a, (byte)0x8f, (byte)0x26, (byte)0x3b, (byte)0xe6, (byte)0x86, (byte)0x35, (byte)0x76, (byte)0xeb, (byte)0x03, (byte)0x62, (byte)0xe2, (byte)0x8c, (byte)0x82, (byte)0x8f, (byte)0x01, (byte)0x07, (byte)0xa3, (byte)0x37, (byte)0x9d, (byte)0x34, (byte)0xba, (byte)0xb1, (byte)0x58, (byte)0x6b, (byte)0xf8, (byte)0xc7, (byte)0x70, (byte)0xcd, (byte)0x67 }; byte[] bobSignedPreKeyPrivate = { (byte)0x58, (byte)0x39, (byte)0x00, (byte)0x13, (byte)0x1f, (byte)0xb7, (byte)0x27, (byte)0x99, (byte)0x8b, (byte)0x78, (byte)0x03, (byte)0xfe, (byte)0x6a, (byte)0xc2, (byte)0x2c, (byte)0xc5, (byte)0x91, (byte)0xf3, (byte)0x42, (byte)0xe4, (byte)0xe4, (byte)0x2a, (byte)0x8c, (byte)0x8d, (byte)0x5d, (byte)0x78, (byte)0x19, (byte)0x42, (byte)0x09, (byte)0xb8, (byte)0xd2, (byte)0x53 }; byte[] senderChain = { (byte)0x97, (byte)0x97, (byte)0xca, (byte)0xca, (byte)0x53, (byte)0xc9, (byte)0x89, (byte)0xbb, (byte)0xe2, (byte)0x29, (byte)0xa4, (byte)0x0c, (byte)0xa7, (byte)0x72, (byte)0x70, (byte)0x10, (byte)0xeb, (byte)0x26, (byte)0x04, (byte)0xfc, (byte)0x14, (byte)0x94, (byte)0x5d, (byte)0x77, (byte)0x95, (byte)0x8a, (byte)0x0a, (byte)0xed, (byte)0xa0, (byte)0x88, (byte)0xb4, (byte)0x4d }; IdentityKey bobIdentityKeyPublic = new IdentityKey(bobIdentityPublic, 0); IEcPrivateKey bobIdentityKeyPrivate = Curve.DecodePrivatePoint(bobIdentityPrivate); IdentityKeyPair bobIdentityKey = new IdentityKeyPair(bobIdentityKeyPublic, bobIdentityKeyPrivate); IEcPublicKey bobEphemeralPublicKey = Curve.DecodePoint(bobPublic, 0); IEcPrivateKey bobEphemeralPrivateKey = Curve.DecodePrivatePoint(bobPrivate); EcKeyPair bobEphemeralKey = new EcKeyPair(bobEphemeralPublicKey, bobEphemeralPrivateKey); EcKeyPair bobBaseKey = bobEphemeralKey; EcKeyPair bobSignedPreKey = new EcKeyPair(Curve.DecodePoint(bobSignedPreKeyPublic, 0), Curve.DecodePrivatePoint(bobSignedPreKeyPrivate)); IEcPublicKey aliceBasePublicKey = Curve.DecodePoint(aliceBasePublic, 0); IEcPublicKey aliceEphemeralPublicKey = Curve.DecodePoint(aliceEphemeralPublic, 0); IdentityKey aliceIdentityPublicKey = new IdentityKey(aliceIdentityPublic, 0); BobSignalProtocolParameters parameters = BobSignalProtocolParameters.NewBuilder() .SetOurIdentityKey(bobIdentityKey) .SetOurSignedPreKey(bobSignedPreKey) .SetOurRatchetKey(bobEphemeralKey) .SetOurOneTimePreKey(May <EcKeyPair> .NoValue) .SetTheirIdentityKey(aliceIdentityPublicKey) .SetTheirBaseKey(aliceBasePublicKey) .Create(); SessionState session = new SessionState(); RatchetingSession.InitializeSession(session, parameters); Assert.AreEqual <IdentityKey>(session.GetLocalIdentityKey(), bobIdentityKey.GetPublicKey()); Assert.AreEqual <IdentityKey>(session.GetRemoteIdentityKey(), aliceIdentityPublicKey); CollectionAssert.AreEqual(session.GetSenderChainKey().GetKey(), senderChain); }