Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
Poly1305.cs
1using System;
2using System.IO;
3using System.Numerics;
4using System.Threading.Tasks;
5
7{
12 public class Poly1305
13 {
14 private readonly static BigInteger p = BigInteger.Pow(2, 130) - 5;
15 private readonly BigInteger r;
16 private readonly BigInteger s;
17
23 public Poly1305(byte[] Key)
24 {
25 if (Key.Length != 32)
26 throw new ArgumentException("Poly1305 keys must be 32 bytes (256 bits) long.", nameof(Key));
27
28 byte[] rBin = new byte[(Key[15] & 0x80) != 0 ? 17 : 16];
29 byte[] sBin = new byte[(Key[31] & 0x80) != 0 ? 17 : 16];
30
31 Array.Copy(Key, 0, rBin, 0, 16);
32 Array.Copy(Key, 16, sBin, 0, 16);
33
34 rBin[3] &= 15;
35 rBin[7] &= 15;
36 rBin[11] &= 15;
37 rBin[15] &= 15;
38 rBin[4] &= 252;
39 rBin[8] &= 252;
40 rBin[12] &= 252;
41
42 this.r = new BigInteger(rBin);
43 this.s = new BigInteger(sBin);
44 }
45
53 public static Poly1305 FromChaCha20(byte[] Key, byte[] Nonce)
54 {
55 ChaCha20 Cipher = new ChaCha20(Key, 0, Nonce);
56 byte[] Key2 = Cipher.GetBytes(32);
57 return new Poly1305(Key2);
58 }
59
65 public byte[] CalcMac(byte[] Data)
66 {
67 int i = 0;
68 int c = Data.Length;
69 byte[] Bin = new byte[17];
70 int j;
71 BigInteger Accumulator = BigInteger.Zero;
72
73 while (i < c)
74 {
75 j = Math.Min(c - i, 16);
76 Array.Copy(Data, i, Bin, 0, j);
77 i += j;
78 Bin[j++] = 1;
79 while (j < 17)
80 Bin[j++] = 0;
81
82 Accumulator = BigInteger.Remainder((Accumulator + new BigInteger(Bin)) * this.r, p);
83 }
84
85 Accumulator += this.s;
86
87 byte[] Result = Accumulator.ToByteArray();
88
89 if (Result.Length != 16)
90 Array.Resize(ref Result, 16);
91
92 return Result;
93 }
94
100 public async Task<byte[]> CalcMac(Stream Data)
101 {
102 long i = 0;
103 long c = Data.Length;
104 byte[] Bin = new byte[17];
105 int j;
106 BigInteger Accumulator = BigInteger.Zero;
107
108 while (i < c)
109 {
110 j = (int)Math.Min(c - i, 16);
111 if (j != await Data.ReadAsync(Bin, 0, j))
112 throw new IOException("Unexpected end of file.");
113
114 i += j;
115 Bin[j++] = 1;
116 while (j < 17)
117 Bin[j++] = 0;
118
119 Accumulator = BigInteger.Remainder((Accumulator + new BigInteger(Bin)) * this.r, p);
120 }
121
122 Accumulator += this.s;
123
124 byte[] Result = Accumulator.ToByteArray();
125
126 if (Result.Length != 16)
127 Array.Resize(ref Result, 16);
128
129 return Result;
130 }
131
132 }
133}
ChaCha20 encryptor, as defined in RFC 8439: https://tools.ietf.org/html/rfc8439
Definition: ChaCha20.cs:12
byte[] GetBytes(int NrBytes)
Gets the next number of bytes in the stream.
Definition: ChaCha20.cs:160
Poly1305 authenticator, as defined in RFC 8439: https://tools.ietf.org/html/rfc8439
Definition: Poly1305.cs:13
Poly1305(byte[] Key)
Poly1305 authenticator, as defined in RFC 8439: https://tools.ietf.org/html/rfc8439
Definition: Poly1305.cs:23
static Poly1305 FromChaCha20(byte[] Key, byte[] Nonce)
Prepares a Poly1305 instance using ChaCha20 and Counter=0 to generate the corresponding key.
Definition: Poly1305.cs:53
byte[] CalcMac(byte[] Data)
Calculates a message authentication code (MAC).
Definition: Poly1305.cs:65
async Task< byte[]> CalcMac(Stream Data)
Calculates a message authentication code (MAC).
Definition: Poly1305.cs:100