Skip to content
This repository has been archived by the owner on Jan 29, 2024. It is now read-only.

[WIP] Omemo signauture #173

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions Component_Tests/Classes/Crypto/Omemo/Test_KeyHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,37 @@ public void Test_SignPreKey()
Assert.AreEqual(sigBase64, sigRefBase64);
}
}

[TestCategory("Crypto")]
[TestMethod]
public void Test_Signing()
{
ECPrivKeyModel identityPriv = new ECPrivKeyModel(SharedUtils.HexStringToByteArray("1498b5467a63dffa2dc9d9e069caf075d16fc33fdd4c3b01bfadae6433767d93"));
ECPubKeyModel identityPub = new ECPubKeyModel(SharedUtils.HexStringToByteArray("05b7a3c12dc0c8c748ab07525b701122b88bd78f600c76342d27f25e5f92444cde"));

ECPrivKeyModel prePriv = new ECPrivKeyModel(SharedUtils.HexStringToByteArray("181c0ed79c361f2d773f3aa8d5934569395a1c1b4a8514d140a7dcde92688579"));
ECPubKeyModel prePub = new ECPubKeyModel(SharedUtils.HexStringToByteArray("05b30aad2471f7186bdb34951747cf81a67245144260e20ffe5bf7748202d6572c"));
PreKeyModel preKey = new PreKeyModel(prePriv, prePub, 2);

byte[] sig = KeyHelper.SignPreKey(preKey, identityPriv);
string sig16 = SharedUtils.ToHexString(sig);
Assert.IsTrue(KeyHelper.VerifySignature(identityPub, prePub, sig));
}

[TestCategory("Crypto")]
[TestMethod]
public void Test_VerifySignature()
{
ECPubKeyModel identityPub = new ECPubKeyModel(SharedUtils.HexStringToByteArray("05b7a3c12dc0c8c748ab07525b701122b88bd78f600c76342d27f25e5f92444cde"));
ECPubKeyModel prePub = new ECPubKeyModel(SharedUtils.HexStringToByteArray("05b30aad2471f7186bdb34951747cf81a67245144260e20ffe5bf7748202d6572c"));
byte[][] sigs = {
SharedUtils.HexStringToByteArray("db0495131504b9acf87696613070088abff5310ad984f3b7623088af6310e2435381f2f726cfcc3edc754549d47e251d873d5b6777dd62a334b5d3fa8afb9f0a")
};

foreach (byte[] sig in sigs)
{
Assert.IsTrue(KeyHelper.VerifySignature(identityPub, prePub, sig));
}
}
}
}
22 changes: 22 additions & 0 deletions Component_Tests/Classes/Crypto/Omemo/Test_Xeddsa25519.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Omemo.Classes.Keys;
using Omemo.Classes.Xeddsa;
using Shared.Classes;

namespace Component_Tests.Classes.Crypto.Omemo
{
[TestClass]
public class Test_Xeddsa25519
{
[TestCategory("Crypto")]
[TestMethod]
public void Test_Signing()
{
ECPrivKeyModel priv = new ECPrivKeyModel(SharedUtils.HexStringToByteArray("1498b5467a63dffa2dc9d9e069caf075d16fc33fdd4c3b01bfadae6433767d93"));
ECPubKeyModel pub = new ECPubKeyModel(SharedUtils.HexStringToByteArray("b7a3c12dc0c8c748ab07525b701122b88bd78f600c76342d27f25e5f92444cde"));
IdentityKeyPairModel identityKeyPair = new IdentityKeyPairModel(priv, pub);
// Xeddsa25519.Sign(identityKeyPair.privKey, pub new );
Xeddsa25519.ToTwistedEdwardsKeyPair(priv);
}
}
}
1 change: 1 addition & 0 deletions Component_Tests/Component_Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
<Compile Include="Classes\Crypto\Omemo\InMemmoryOmemoStorage.cs" />
<Compile Include="Classes\Crypto\Omemo\Test_KeyHelper.cs" />
<Compile Include="Classes\Crypto\Omemo\Test_Omemo.cs" />
<Compile Include="Classes\Crypto\Omemo\Test_Xeddsa25519.cs" />
<Compile Include="Classes\Crypto\Test_CryptoUtils.cs" />
<Compile Include="Classes\Misc\Test_DateTimeParserHelper.cs" />
<Compile Include="Classes\Misc\Test_ConsistentColorGenerator.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Omemo.Classes.Keys
{
public abstract class AbstractECKeyPairModel: AbstractDataTemplate
public class ECKeyPairModel: AbstractDataTemplate
{
//--------------------------------------------------------Attributes:-----------------------------------------------------------------\\
#region --Attributes--
Expand Down Expand Up @@ -38,9 +38,9 @@ public ECPubKeyModel pubKey
#endregion
//--------------------------------------------------------Constructor:----------------------------------------------------------------\\
#region --Constructors--
public AbstractECKeyPairModel() { }
public ECKeyPairModel() { }

public AbstractECKeyPairModel(ECPrivKeyModel privKey, ECPubKeyModel pubKey)
public ECKeyPairModel(ECPrivKeyModel privKey, ECPubKeyModel pubKey)
{
this.privKey = privKey;
this.pubKey = pubKey;
Expand Down Expand Up @@ -86,7 +86,7 @@ private void SetPubKeyProperty(ECPubKeyModel value)
#region --Misc Methods (Public)--
public override bool Equals(object obj)
{
return obj is AbstractECKeyPairModel pair && ((pair.privKey is null && privKey is null) || pair.privKey.Equals(privKey)) && ((pair.pubKey is null && pubKey is null) || pair.pubKey.Equals(pubKey));
return obj is ECKeyPairModel pair && ((pair.privKey is null && privKey is null) || pair.privKey.Equals(privKey)) && ((pair.pubKey is null && pubKey is null) || pair.pubKey.Equals(pubKey));
}

public override int GetHashCode()
Expand Down
6 changes: 3 additions & 3 deletions Omemo/Classes/Keys/ECPrivKeyModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ public class ECPrivKeyModel: ECKeyModel
/// </summary>
public ECPrivKeyModel() { }

public ECPrivKeyModel(byte[] pubKey) : base(pubKey)
public ECPrivKeyModel(byte[] privKey) : base(privKey)
{
if (pubKey.Length == KeyHelper.PUB_KEY_SIZE)
if (privKey.Length == KeyHelper.PUB_KEY_SIZE)
{
return;
}

throw new OmemoKeyException($"Invalid key length {pubKey.Length} - expected {KeyHelper.PRIV_KEY_SIZE}.");
throw new OmemoKeyException($"Invalid key length {privKey.Length} - expected {KeyHelper.PRIV_KEY_SIZE}.");
}

#endregion
Expand Down
2 changes: 1 addition & 1 deletion Omemo/Classes/Keys/EphemeralKeyPairModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/// <summary>
/// Represents a Ed25519 key pair.
/// </summary>
public class EphemeralKeyPairModel: AbstractECKeyPairModel
public class EphemeralKeyPairModel: ECKeyPairModel
{
//--------------------------------------------------------Attributes:-----------------------------------------------------------------\\
#region --Attributes--
Expand Down
2 changes: 1 addition & 1 deletion Omemo/Classes/Keys/GenericECKeyPairModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/// <summary>
/// Represents a generic EC key pair holding a <see cref="ECPubKeyModel"/> and <see cref="ECPrivKeyModel"/>.
/// </summary>
public class GenericECKeyPairModel: AbstractECKeyPairModel
public class GenericECKeyPairModel: ECKeyPairModel
{
//--------------------------------------------------------Attributes:-----------------------------------------------------------------\\
#region --Attributes--
Expand Down
2 changes: 1 addition & 1 deletion Omemo/Classes/Keys/IdentityKeyPairModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/// <summary>
/// Represents a Ed25519 key pair.
/// </summary>
public class IdentityKeyPairModel: AbstractECKeyPairModel
public class IdentityKeyPairModel: ECKeyPairModel
{
//--------------------------------------------------------Attributes:-----------------------------------------------------------------\\
#region --Attributes--
Expand Down
2 changes: 1 addition & 1 deletion Omemo/Classes/Keys/PreKeyModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Omemo.Classes.Keys
{
public class PreKeyModel: AbstractECKeyPairModel
public class PreKeyModel: ECKeyPairModel
{
//--------------------------------------------------------Attributes:-----------------------------------------------------------------\\
#region --Attributes--
Expand Down
69 changes: 69 additions & 0 deletions Omemo/Classes/Xeddsa/ECPoint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using Org.BouncyCastle.Math;

namespace Omemo.Classes.Xeddsa
{
public class ECPoint
{
//--------------------------------------------------------Attributes:-----------------------------------------------------------------\\
#region --Attributes--
public BigInteger y;
public bool s;

#endregion
//--------------------------------------------------------Constructor:----------------------------------------------------------------\\
#region --Constructors--
public ECPoint(byte[] point)
{
// Decoding described in: https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.3
BigInteger tmp = new BigInteger(point);
s = ((point[31] & 0x80) >> 7) == 1;
y = tmp.ClearBit(255);
}

public ECPoint(BigInteger y, bool s)
{
this.y = y;
this.s = s;
}

#endregion
//--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\
#region --Set-, Get- Methods--


#endregion
//--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\
#region --Misc Methods (Public)--
public byte[] Encode()
{
// Encoding described in: https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.2
BigInteger point = new BigInteger(y.ToByteArray());
if (s)
{
point.SetBit(255);
}
else
{
point.ClearBit(255);
}
return point.ToByteArray();
}

#endregion

#region --Misc Methods (Private)--


#endregion

#region --Misc Methods (Protected)--


#endregion
//--------------------------------------------------------Events:---------------------------------------------------------------------\\
#region --Events--


#endregion
}
}
114 changes: 114 additions & 0 deletions Omemo/Classes/Xeddsa/Xeddsa25519.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using System.Diagnostics;
using NSec.Cryptography;
using Omemo.Classes.Keys;
using Org.BouncyCastle.Math;

namespace Omemo.Classes.Xeddsa
{
/// <summary>
/// Notes:
/// Curve25519 -> Montgomery
/// edwards25519 (Ed25519) -> Twisted Edwards
/// Ed25519 is a public-key signature system with several attractive features (https://ed25519.cr.yp.to/)
/// Ed25519 as defined in:
/// https://tools.ietf.org/html/rfc7748
/// https://tools.ietf.org/html/rfc8032
/// </summary>
public class Xeddsa25519
{
//--------------------------------------------------------Attributes:-----------------------------------------------------------------\\
#region --Attributes--
private static readonly BigInteger p = BigInteger.Two.Pow(255).Subtract(BigInteger.ValueOf(19));

private static readonly byte[] MINUS_ONE = new byte[] {0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};

#endregion
//--------------------------------------------------------Constructor:----------------------------------------------------------------\\
#region --Constructors--


#endregion
//--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\
#region --Set-, Get- Methods--


#endregion
//--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\
#region --Misc Methods (Public)--
/// <summary>
/// Signes the given <paramref name="msg"/> and returns the result.
/// </summary>
/// <param name="privKey">The Curve25519 (Montgomery) private key used for signing.</param>
/// <param name="msg">The message that should be signed.</param>
/// <param name="random">64 bytes secure random data used for signing.</param>
/// <returns>The generated signature for the given <paramref name="msg"/>.</returns>
public static byte[] Sign(ECPrivKeyModel privKey, byte[] msg, byte[] random)
{
Debug.Assert(random.Length == 64);
Debug.Assert(msg.Length > 0);

ECKeyPairModel edKeyPair = ToTwistedEdwardsKeyPair(privKey);

Key key = Key.Import(SignatureAlgorithm.Ed25519, edKeyPair.privKey.key, KeyBlobFormat.RawPrivateKey);
return SignatureAlgorithm.Ed25519.Sign(key, msg);
}

#endregion

#region --Misc Methods (Private)--
public static ECKeyPairModel ToTwistedEdwardsKeyPair(ECPrivKeyModel privKey)
{
byte[] A = new byte[Org.BouncyCastle.Math.EC.Rfc7748.X25519.PointSize];
byte[] A2 = new byte[Org.BouncyCastle.Math.EC.Rfc7748.X25519.PointSize];
Org.BouncyCastle.Math.EC.Rfc7748.X25519.ScalarMultBase(privKey.key, 0, A2, 0);
byte[] u = Shared.Classes.SharedUtils.HexStringToByteArray("5866666666666666666666666666666666666666666666666666666666666666");
Org.BouncyCastle.Math.EC.Rfc7748.X25519.ScalarMult(privKey.key, 0, u, 0, A, 0);

byte s = (byte)((A[31] & 0x80) >> 7);
byte[] a = new byte[Org.BouncyCastle.Math.EC.Rfc7748.X25519.PointSize];
privKey.key.CopyTo(a, 0);
byte[] aNeg = new byte[Org.BouncyCastle.Math.EC.Rfc7748.X25519.PointSize];

Org.BouncyCastle.Math.EC.Rfc7748.X25519.ScalarMult(MINUS_ONE, 0, a, 0, aNeg, 0);
sc_cmov(a, aNeg, s);
A[31] &= 0x7F;

return new ECKeyPairModel(new ECPrivKeyModel(a), new ECPubKeyModel(A));
}

private static void sc_cmov(byte[] f, byte[] g, byte b)
{
byte[] x = new byte[32];
for (int count = 0; count < 32; count++)
{
x[count] = (byte)(f[count] ^ g[count]);
}
b = (byte)-b;
for (int count = 0; count < 32; count++)
{
x[count] &= b;
}

for (int count = 0; count < 32; count++)
{
f[count] = (byte)(f[count] ^ x[count]);
}
}


#endregion

#region --Misc Methods (Protected)--


#endregion
//--------------------------------------------------------Events:---------------------------------------------------------------------\\
#region --Events--


#endregion
}
}
5 changes: 4 additions & 1 deletion Omemo/Omemo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
<Compile Include="Classes\KeyHelper.cs" />
<Compile Include="Classes\Keys\Bundle.cs" />
<Compile Include="Classes\Keys\ECKeyModel.cs" />
<Compile Include="Classes\Keys\AbstractECKeyPairModel.cs" />
<Compile Include="Classes\Keys\ECKeyPairModel.cs" />
<Compile Include="Classes\Keys\ECPrivKeyModel.cs" />
<Compile Include="Classes\Keys\ECPubKeyModel.cs" />
<Compile Include="Classes\Keys\EphemeralKeyPairModel.cs" />
Expand All @@ -150,6 +150,8 @@
<Compile Include="Classes\SkippedMessageKeyModel.cs" />
<Compile Include="Classes\SkippedMessageKeyGroupModel.cs" />
<Compile Include="Classes\SkippedMessageKeyGroupsModel.cs" />
<Compile Include="Classes\Xeddsa\ECPoint.cs" />
<Compile Include="Classes\Xeddsa\Xeddsa25519.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\Omemo.rd.xml" />
</ItemGroup>
Expand Down Expand Up @@ -182,6 +184,7 @@
<Name>Visual C++ 2015-2019 UWP Desktop Runtime for native apps</Name>
</SDKReference>
</ItemGroup>
<ItemGroup />
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
Expand Down