Mercurial > hg > ucis.core
annotate NaCl/APIv2.cs @ 54:ba4e2cb031e0
Added general purpose tar archive reader class
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Wed, 02 Oct 2013 21:17:30 +0200 |
parents | 29cf42a12c34 |
children | 6aca18ee4ec6 |
rev | line source |
---|---|
20 | 1 ???using System; |
43
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
2 using System.Globalization; |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
3 using UCIS.Util; |
20 | 4 using curve25519xsalsa20poly1305impl = UCIS.NaCl.crypto_box.curve25519xsalsa20poly1305; |
5 using edwards25519sha512batchimpl = UCIS.NaCl.crypto_sign.edwards25519sha512batch; | |
6 using xsalsa20poly1305impl = UCIS.NaCl.crypto_secretbox.xsalsa20poly1305; | |
7 | |
8 namespace UCIS.NaCl.v2 { | |
9 public class curve25519keypair { | |
43
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
10 private Byte[] secretkey; |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
11 private Byte[] publickey = null; |
20 | 12 |
13 public curve25519keypair() { | |
14 curve25519xsalsa20poly1305impl.crypto_box_keypair(out publickey, out secretkey); | |
15 } | |
16 public curve25519keypair(Byte[] secretkey) { | |
17 this.secretkey = secretkey; | |
18 } | |
43
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
19 public curve25519keypair(String secretkey) { |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
20 this.secretkey = DecodeHexString(secretkey, curve25519xsalsa20poly1305impl.SECRETKEYBYTES); |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
21 } |
20 | 22 public curve25519keypair(Byte[] secretkey, Byte[] publickey) { |
23 if (publickey.Length != curve25519xsalsa20poly1305impl.PUBLICKEYBYTES) throw new ArgumentOutOfRangeException("publickey"); | |
24 if (secretkey.Length != curve25519xsalsa20poly1305impl.SECRETKEYBYTES) throw new ArgumentOutOfRangeException("secretkey"); | |
25 this.secretkey = secretkey; | |
26 this.publickey = publickey; | |
27 } | |
43
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
28 public Byte[] PublicKey { |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
29 get { |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
30 if (publickey == null) publickey = curve25519xsalsa20poly1305impl.crypto_box_getpublickey(secretkey); |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
31 return publickey; |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
32 } |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
33 } |
20 | 34 public Byte[] SecretKey { get { return secretkey; } } |
43
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
35 internal static Byte[] DecodeHexString(String str, int length) { |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
36 if (str.Length != length * 2) throw new ArgumentException("str", "Incorrect key length"); |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
37 Byte[] bytes = new Byte[length]; |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
38 for (int i = 0; i < length; i++) bytes[i] = Byte.Parse(str.Substring(i * 2, 2), NumberStyles.HexNumber); |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
39 return bytes; |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
40 } |
20 | 41 } |
42 public class curve25519xsalsa20poly1305 : xsalsa20poly1305 { | |
43
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
43 public Byte[] PublicKey { get; private set; } |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
44 public curve25519keypair SecretKey { get; private set; } |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
45 public curve25519xsalsa20poly1305(String publickey, String secretkey) |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
46 : this(curve25519keypair.DecodeHexString(publickey, curve25519xsalsa20poly1305impl.PUBLICKEYBYTES), new curve25519keypair(secretkey)) { |
20 | 47 } |
48 public curve25519xsalsa20poly1305(Byte[] publickey, Byte[] secretkey) | |
43
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
49 : this(publickey, new curve25519keypair(secretkey)) { |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
50 } |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
51 public curve25519xsalsa20poly1305(Byte[] publickey, curve25519keypair secretkey) |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
52 : base(curve25519xsalsa20poly1305impl.crypto_box_beforenm(publickey, secretkey.SecretKey)) { |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
53 this.PublicKey = publickey; |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
54 this.SecretKey = secretkey; |
20 | 55 } |
56 } | |
57 public class xsalsa20poly1305 { | |
43
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
58 protected Byte[] sharedkey = new Byte[xsalsa20poly1305impl.KEYBYTES]; |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
59 Byte[] nonce = new Byte[xsalsa20poly1305impl.NONCEBYTES]; |
20 | 60 |
61 public int SharedKeySize { get { return xsalsa20poly1305impl.KEYBYTES; } } | |
62 | |
63 public xsalsa20poly1305(Byte[] sharedkey) : this(sharedkey, null) { } | |
64 public xsalsa20poly1305(Byte[] sharedkey, Byte[] nonce) { | |
43
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
65 if (sharedkey == null) throw new ArgumentNullException("secretkey"); |
20 | 66 if (sharedkey.Length != xsalsa20poly1305impl.KEYBYTES) throw new ArgumentOutOfRangeException("secretkey", "The key size does not match the expected key length"); |
43
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
67 sharedkey.CopyTo(this.sharedkey, 0); |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
68 if (nonce != null) this.Nonce = nonce; |
20 | 69 } |
70 | |
71 public Byte[] Nonce { | |
72 get { return this.nonce; } | |
43
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
73 set { NonceValue = value; } |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
74 } |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
75 public Byte[] NonceValue { |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
76 get { return ArrayUtil.ToArray(nonce); } |
20 | 77 set { |
78 if (ReferenceEquals(value, null)) throw new ArgumentNullException("value"); | |
79 if (value.Length > xsalsa20poly1305impl.NONCEBYTES) throw new ArgumentOutOfRangeException("value", "Nonce is too big"); | |
80 value.CopyTo(nonce, 0); | |
81 Array.Clear(this.nonce, value.Length, this.nonce.Length - value.Length); | |
82 } | |
83 } | |
43
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
84 public Byte[] NonceBuffer { |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
85 get { return this.nonce; } |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
86 set { |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
87 if (ReferenceEquals(value, null)) throw new ArgumentNullException("value"); |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
88 if (value.Length > xsalsa20poly1305impl.NONCEBYTES) throw new ArgumentOutOfRangeException("value", "Incorrect nonce length"); |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
89 this.nonce = value; |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
90 } |
29cf42a12c34
Added convenience functions in NaCl API and ArrayUtils
Ivo Smits <Ivo@UCIS.nl>
parents:
20
diff
changeset
|
91 } |
20 | 92 |
93 public Byte[] SharedKey { | |
94 get { return sharedkey; } | |
95 } | |
96 | |
97 public unsafe Byte[] Encrypt(Byte[] data) { | |
98 return Encrypt(data, 0, data.Length); | |
99 } | |
100 public unsafe Byte[] Encrypt(Byte[] data, int offset, int count) { | |
101 if (ReferenceEquals(data, null)) throw new ArgumentNullException("data"); | |
102 if (offset < 0) throw new ArgumentOutOfRangeException("offset", "Offset can not be negative"); | |
103 if (data.Length < offset + count) throw new ArgumentOutOfRangeException("count", "The specified range is outside of the array"); | |
104 Byte[] ret = new Byte[GetEncryptedSize(count)]; | |
105 fixed (Byte* mp = data, cp = ret, np = nonce, kp = sharedkey) { | |
106 if (xsalsa20poly1305impl.crypto_secretbox_nopad(cp, mp + offset, (ulong)count, np, kp) != 0) throw new InvalidOperationException("Encryption failed"); | |
107 } | |
108 return ret; | |
109 } | |
110 public unsafe int EncryptTo(Byte[] data, int offset, int count, Byte[] outdata, int outoffset, int outcount) { | |
111 if (ReferenceEquals(data, null)) throw new ArgumentNullException("data"); | |
112 if (offset < 0) throw new ArgumentOutOfRangeException("offset", "Offset can not be negative"); | |
113 if (data.Length < offset + count) throw new ArgumentOutOfRangeException("count", "The specified range is outside of the array"); | |
114 if (ReferenceEquals(outdata, null)) throw new ArgumentNullException("outdata"); | |
115 if (outoffset < 0) throw new ArgumentOutOfRangeException("outoffset", "Offset can not be negative"); | |
116 if (outdata.Length < outoffset + outcount) throw new ArgumentOutOfRangeException("outcount", "The specified range is outside of the array"); | |
117 int retcount = GetEncryptedSize(count); | |
118 if (outcount < retcount) throw new ArgumentOutOfRangeException("outcount", "The output buffer is too small"); | |
119 fixed (Byte* mp = data, cp = outdata, np = nonce, kp = sharedkey) { | |
120 if (xsalsa20poly1305impl.crypto_secretbox_nopad(cp + outoffset, mp + offset, (ulong)count, np, kp) != 0) throw new InvalidOperationException("Encryption failed"); | |
121 } | |
122 return outcount; | |
123 } | |
124 /*public unsafe void EncryptInplace(Byte[] data, int offset, int count) { | |
125 if (ReferenceEquals(data, null)) throw new ArgumentNullException("data"); | |
126 if (offset < 0) throw new ArgumentOutOfRangeException("offset", "Offset can not be negative"); | |
127 if (data.Length < offset + count) throw new ArgumentOutOfRangeException("count", "The specified range is outside of the array"); | |
128 if (count < 16) throw new ArgumentOutOfRangeException("count", "count should be at least 16"); | |
129 fixed (Byte* mp = data, np = nonce, kp = sharedkey) { | |
130 if (xsalsa20poly1305impl.crypto_secretbox_inplace_nopad(mp + offset, (ulong)count, np, kp) != 0) throw new InvalidOperationException("Encryption failed"); | |
131 } | |
132 }*/ | |
133 public int GetEncryptedSize(int size) { | |
134 return size + 16; | |
135 } | |
136 | |
137 public unsafe Byte[] Decrypt(Byte[] data) { | |
138 return Decrypt(data, 0, data.Length); | |
139 } | |
140 public unsafe Byte[] Decrypt(Byte[] data, int offset, int count) { | |
141 if (ReferenceEquals(data, null)) throw new ArgumentNullException("data"); | |
142 if (offset < 0) throw new ArgumentOutOfRangeException("offset", "Offset can not be negative"); | |
143 if (data.Length < offset + count) throw new ArgumentOutOfRangeException("count", "The specified range is outside of the array"); | |
144 if (count < 16) return null; | |
145 Byte[] ret = new Byte[GetDecryptedSize(count)]; | |
146 fixed (Byte* cp = data, mp = ret, np = nonce, kp = sharedkey) { | |
147 if (xsalsa20poly1305impl.crypto_secretbox_open_nopad(mp, cp + offset, (ulong)count, np, kp) != 0) return null; | |
148 } | |
149 return ret; | |
150 } | |
151 public unsafe int? DecryptTo(Byte[] data, int offset, int count, Byte[] outdata, int outoffset, int outcount) { | |
152 if (ReferenceEquals(data, null)) throw new ArgumentNullException("data"); | |
153 if (offset < 0) throw new ArgumentOutOfRangeException("offset", "Offset can not be negative"); | |
154 if (data.Length < offset + count) throw new ArgumentOutOfRangeException("count", "The specified range is outside of the array"); | |
155 if (count < 16) return null; | |
156 if (ReferenceEquals(outdata, null)) throw new ArgumentNullException("outdata"); | |
157 if (outoffset < 0) throw new ArgumentOutOfRangeException("outoffset", "Offset can not be negative"); | |
158 if (outdata.Length < outoffset + outcount) throw new ArgumentOutOfRangeException("outcount", "The specified range is outside of the array"); | |
159 int retcount = GetDecryptedSize(count); | |
160 if (outcount < retcount) throw new ArgumentOutOfRangeException("outcount", "The output buffer is too small"); | |
161 fixed (Byte* cp = data, mp = outdata, np = nonce, kp = sharedkey) { | |
162 if (xsalsa20poly1305impl.crypto_secretbox_open_nopad(mp + outoffset, cp + offset, (ulong)count, np, kp) != 0) return null; | |
163 } | |
164 return retcount; | |
165 } | |
166 public unsafe ArraySegment<Byte>? DecryptInplace(Byte[] data, int offset, int count) { | |
167 if (ReferenceEquals(data, null)) throw new ArgumentNullException("data"); | |
168 if (offset < 0) throw new ArgumentOutOfRangeException("offset", "Offset can not be negative"); | |
169 if (data.Length < offset + count) throw new ArgumentOutOfRangeException("count", "The specified range is outside of the array"); | |
170 if (count < 16) return null; | |
171 fixed (Byte* cp = data, np = nonce, kp = sharedkey) { | |
172 if (xsalsa20poly1305impl.crypto_secretbox_open_inplace_nopad(cp + offset, (ulong)count, np, kp) != 0) return null; | |
173 } | |
174 return new ArraySegment<byte>(data, offset + 16, count - 16); | |
175 } | |
176 public int GetDecryptedSize(int size) { | |
177 if (size < 16) return -1; | |
178 return size - 16; | |
179 } | |
180 | |
181 public Boolean Verify(Byte[] data) { | |
182 return Verify(data, 0, data.Length); | |
183 } | |
184 public unsafe Boolean Verify(Byte[] data, int offset, int count) { | |
185 if (ReferenceEquals(data, null)) throw new ArgumentNullException("data"); | |
186 if (offset < 0) throw new ArgumentOutOfRangeException("offset", "Offset can not be negative"); | |
187 if (data.Length < offset + count) throw new ArgumentOutOfRangeException("count", "The specified range is outside of the array"); | |
188 if (count < 16) return false; | |
189 Byte[] ret = new Byte[GetDecryptedSize(count)]; | |
190 fixed (Byte* cp = data, np = nonce, kp = sharedkey) { | |
191 return xsalsa20poly1305impl.crypto_secretbox_verify(cp + offset, (ulong)count, np, kp); | |
192 } | |
193 } | |
194 | |
195 public Byte[] GenerateRandomNonce() { | |
196 randombytes.generate(nonce); | |
197 return nonce; | |
198 } | |
199 public void IncrementNonceLE() { | |
200 for (int i = 0; i < nonce.Length && ++nonce[i] == 0; i++) ; | |
201 } | |
202 public void IncrementNonceBE() { | |
203 for (int i = nonce.Length - 1; i >= 0 && ++nonce[i] == 0; i--) ; | |
204 } | |
205 | |
206 public xsalsa20poly1305 Clone() { | |
207 return new xsalsa20poly1305(sharedkey, nonce); | |
208 } | |
209 } | |
210 public class edwards25519sha512batch { | |
211 public Byte[] Sign(Byte[] message, Byte[] secretkey) { | |
212 return edwards25519sha512batchimpl.crypto_sign(message, secretkey); | |
213 } | |
214 public int GetSignedSize(int size) { | |
215 return size + 64; | |
216 } | |
217 public Byte[] Open(Byte[] signed, Byte[] publickey) { | |
218 return edwards25519sha512batchimpl.crypto_sign_open(signed, publickey); | |
219 } | |
220 public unsafe Boolean Verify(Byte[] signed, Byte[] publickey) { | |
221 if (publickey.Length != edwards25519sha512batchimpl.PUBLICKEYBYTES) throw new ArgumentException("publickey.Length != PUBLICKEYBYTES"); | |
222 UInt64 mlen; | |
223 fixed (Byte* smp = signed, pkp = publickey) return edwards25519sha512batchimpl.crypto_sign_open(null, out mlen, smp, (ulong)signed.Length, pkp) == 0; | |
224 } | |
225 public Byte[] Extract(Byte[] signed) { | |
226 if (signed.Length < 64) return null; | |
227 Byte[] ret = new Byte[signed.Length - 64]; | |
228 Buffer.BlockCopy(signed, 32, ret, 0, ret.Length); | |
229 return ret; | |
230 } | |
231 public int GetExtractedSize(int size) { | |
232 if (size < 64) return -1; | |
233 return size - 64; | |
234 } | |
235 } | |
236 } |