mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-22 13:55:46 +00:00
Switch to crypto_api_chachapoly crate
This crate exposes both the ChaCha20Poly1305 IETF construction, and the underlying ChaCha20 IETF primitive, removing the need for depending on our own fork of the previous chacha20-poly1305-aead crate.
This commit is contained in:
parent
e17e4b1346
commit
6dcb4040af
26
Cargo.lock
generated
26
Cargo.lock
generated
@ -114,14 +114,6 @@ name = "byteorder"
|
|||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chacha20-poly1305-aead"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "git+https://github.com/gtank/chacha20-poly1305-aead?rev=aefc71f95e8bc43f2070e3c5b08130d9c86bbf4f#aefc71f95e8bc43f2070e3c5b08130d9c86bbf4f"
|
|
||||||
dependencies = [
|
|
||||||
"constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "constant_time_eq"
|
name = "constant_time_eq"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
@ -132,6 +124,19 @@ name = "crossbeam"
|
|||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto_api"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto_api_chachapoly"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crypto_api 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
@ -508,7 +513,7 @@ version = "0.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)",
|
"blake2-rfc 0.2.18 (git+https://github.com/gtank/blake2-rfc?rev=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9)",
|
||||||
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"chacha20-poly1305-aead 0.1.2 (git+https://github.com/gtank/chacha20-poly1305-aead?rev=aefc71f95e8bc43f2070e3c5b08130d9c86bbf4f)",
|
"crypto_api_chachapoly 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ff 0.4.0",
|
"ff 0.4.0",
|
||||||
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -563,9 +568,10 @@ dependencies = [
|
|||||||
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
|
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
|
||||||
"checksum byte-tools 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "980479e6fde23246dfb54d47580d66b4e99202e7579c5eaa9fe10ecb5ebd2182"
|
"checksum byte-tools 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "980479e6fde23246dfb54d47580d66b4e99202e7579c5eaa9fe10ecb5ebd2182"
|
||||||
"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87"
|
"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87"
|
||||||
"checksum chacha20-poly1305-aead 0.1.2 (git+https://github.com/gtank/chacha20-poly1305-aead?rev=aefc71f95e8bc43f2070e3c5b08130d9c86bbf4f)" = "<none>"
|
|
||||||
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
|
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
|
||||||
"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
|
"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
|
||||||
|
"checksum crypto_api 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f855e87e75a4799e18b8529178adcde6fd4f97c1449ff4821e747ff728bb102"
|
||||||
|
"checksum crypto_api_chachapoly 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9ee35dbace0831b5fe7cb9b43eb029aa14a10f594a115025d4628a2baa63ab"
|
||||||
"checksum digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603"
|
"checksum digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603"
|
||||||
"checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"
|
"checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"
|
||||||
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||||
|
@ -7,6 +7,7 @@ authors = [
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1"
|
byteorder = "1"
|
||||||
|
crypto_api_chachapoly = "0.1"
|
||||||
ff = { path = "../ff" }
|
ff = { path = "../ff" }
|
||||||
hex = "0.3"
|
hex = "0.3"
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
@ -18,7 +19,3 @@ sha2 = "0.8"
|
|||||||
[dependencies.blake2-rfc]
|
[dependencies.blake2-rfc]
|
||||||
git = "https://github.com/gtank/blake2-rfc"
|
git = "https://github.com/gtank/blake2-rfc"
|
||||||
rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9"
|
rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9"
|
||||||
|
|
||||||
[dependencies.chacha20-poly1305-aead]
|
|
||||||
git = "https://github.com/gtank/chacha20-poly1305-aead"
|
|
||||||
rev = "aefc71f95e8bc43f2070e3c5b08130d9c86bbf4f"
|
|
||||||
|
@ -3,7 +3,7 @@ extern crate lazy_static;
|
|||||||
|
|
||||||
extern crate blake2_rfc;
|
extern crate blake2_rfc;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
extern crate chacha20_poly1305_aead;
|
extern crate crypto_api_chachapoly;
|
||||||
extern crate ff;
|
extern crate ff;
|
||||||
extern crate hex;
|
extern crate hex;
|
||||||
extern crate pairing;
|
extern crate pairing;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use blake2_rfc::blake2b::{Blake2b, Blake2bResult};
|
use blake2_rfc::blake2b::{Blake2b, Blake2bResult};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
use chacha20_poly1305_aead::{self, as_bytes::AsBytes, chacha20::ChaCha20};
|
use crypto_api_chachapoly::{ChaCha20Ietf, ChachaPolyIetf};
|
||||||
use ff::{PrimeField, PrimeFieldRepr};
|
use ff::{PrimeField, PrimeFieldRepr};
|
||||||
use pairing::bls12_381::{Bls12, Fr};
|
use pairing::bls12_381::{Bls12, Fr};
|
||||||
use rand::{OsRng, Rng};
|
use rand::{OsRng, Rng};
|
||||||
@ -240,19 +240,14 @@ impl SaplingNoteEncryption {
|
|||||||
input.extend_from_slice(&self.memo.0);
|
input.extend_from_slice(&self.memo.0);
|
||||||
assert_eq!(input.len(), NOTE_PLAINTEXT_SIZE);
|
assert_eq!(input.len(), NOTE_PLAINTEXT_SIZE);
|
||||||
|
|
||||||
let mut ciphertext = Vec::with_capacity(NOTE_PLAINTEXT_SIZE);
|
|
||||||
let tag = chacha20_poly1305_aead::encrypt(
|
|
||||||
&key.as_bytes(),
|
|
||||||
&[0u8; 12],
|
|
||||||
&[],
|
|
||||||
&input,
|
|
||||||
&mut ciphertext,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut output = [0u8; ENC_CIPHERTEXT_SIZE];
|
let mut output = [0u8; ENC_CIPHERTEXT_SIZE];
|
||||||
output[0..NOTE_PLAINTEXT_SIZE].copy_from_slice(&ciphertext);
|
assert_eq!(
|
||||||
output[NOTE_PLAINTEXT_SIZE..ENC_CIPHERTEXT_SIZE].copy_from_slice(&tag);
|
ChachaPolyIetf::aead_cipher()
|
||||||
|
.seal_to(&mut output, &input, &[], &key.as_bytes(), &[0u8; 12])
|
||||||
|
.unwrap(),
|
||||||
|
ENC_CIPHERTEXT_SIZE
|
||||||
|
);
|
||||||
|
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,23 +258,26 @@ impl SaplingNoteEncryption {
|
|||||||
) -> [u8; OUT_CIPHERTEXT_SIZE] {
|
) -> [u8; OUT_CIPHERTEXT_SIZE] {
|
||||||
let key = prf_ock(&self.ovk, &cv, &cmu, &self.epk);
|
let key = prf_ock(&self.ovk, &cv, &cmu, &self.epk);
|
||||||
|
|
||||||
let mut input = [0u8; OUT_PLAINTEXT_SIZE];
|
let mut buf = [0u8; OUT_CIPHERTEXT_SIZE];
|
||||||
self.note.pk_d.write(&mut input[0..32]).unwrap();
|
self.note.pk_d.write(&mut buf[0..32]).unwrap();
|
||||||
self.esk
|
self.esk
|
||||||
.into_repr()
|
.into_repr()
|
||||||
.write_le(&mut input[32..OUT_PLAINTEXT_SIZE])
|
.write_le(&mut buf[32..OUT_PLAINTEXT_SIZE])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut buffer = Vec::with_capacity(OUT_PLAINTEXT_SIZE);
|
assert_eq!(
|
||||||
let tag =
|
ChachaPolyIetf::aead_cipher()
|
||||||
chacha20_poly1305_aead::encrypt(key.as_bytes(), &[0u8; 12], &[], &input, &mut buffer)
|
.seal(
|
||||||
.unwrap();
|
&mut buf,
|
||||||
|
OUT_PLAINTEXT_SIZE,
|
||||||
let mut output = [0u8; OUT_CIPHERTEXT_SIZE];
|
&[],
|
||||||
output[0..OUT_PLAINTEXT_SIZE].copy_from_slice(&buffer);
|
key.as_bytes(),
|
||||||
output[OUT_PLAINTEXT_SIZE..OUT_CIPHERTEXT_SIZE].copy_from_slice(&tag[..]);
|
&[0u8; 12]
|
||||||
|
)
|
||||||
output
|
.unwrap(),
|
||||||
|
OUT_CIPHERTEXT_SIZE
|
||||||
|
);
|
||||||
|
buf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,16 +327,19 @@ pub fn try_sapling_note_decryption(
|
|||||||
let shared_secret = sapling_ka_agree(ivk, epk);
|
let shared_secret = sapling_ka_agree(ivk, epk);
|
||||||
let key = kdf_sapling(&shared_secret, &epk);
|
let key = kdf_sapling(&shared_secret, &epk);
|
||||||
|
|
||||||
let mut plaintext = Vec::with_capacity(NOTE_PLAINTEXT_SIZE);
|
let mut plaintext = vec![0; ENC_CIPHERTEXT_SIZE];
|
||||||
chacha20_poly1305_aead::decrypt(
|
assert_eq!(
|
||||||
key.as_bytes(),
|
ChachaPolyIetf::aead_cipher()
|
||||||
&[0u8; 12],
|
.open_to(
|
||||||
&[],
|
&mut plaintext,
|
||||||
&enc_ciphertext[..NOTE_PLAINTEXT_SIZE],
|
&enc_ciphertext,
|
||||||
&enc_ciphertext[NOTE_PLAINTEXT_SIZE..],
|
&[],
|
||||||
&mut plaintext,
|
key.as_bytes(),
|
||||||
)
|
&[0u8; 12]
|
||||||
.ok()?;
|
)
|
||||||
|
.ok()?,
|
||||||
|
NOTE_PLAINTEXT_SIZE
|
||||||
|
);
|
||||||
|
|
||||||
let (note, to) = parse_note_plaintext_minus_memo(ivk, cmu, &plaintext)?;
|
let (note, to) = parse_note_plaintext_minus_memo(ivk, cmu, &plaintext)?;
|
||||||
|
|
||||||
@ -364,18 +365,24 @@ pub fn try_sapling_compact_note_decryption(
|
|||||||
let shared_secret = sapling_ka_agree(ivk, epk);
|
let shared_secret = sapling_ka_agree(ivk, epk);
|
||||||
let key = kdf_sapling(&shared_secret, &epk);
|
let key = kdf_sapling(&shared_secret, &epk);
|
||||||
|
|
||||||
let mut chacha20 = ChaCha20::new(key.as_bytes(), &[0u8; 12]);
|
// Prefix plaintext with 64 zero-bytes to skip over Poly1305 keying output
|
||||||
// Skip over Poly1305 keying output
|
const CHACHA20_BLOCK_SIZE: usize = 64;
|
||||||
chacha20.next();
|
let mut plaintext = Vec::with_capacity(CHACHA20_BLOCK_SIZE + COMPACT_NOTE_SIZE);
|
||||||
|
plaintext.extend_from_slice(&[0; CHACHA20_BLOCK_SIZE]);
|
||||||
let mut plaintext = Vec::with_capacity(COMPACT_NOTE_SIZE);
|
|
||||||
plaintext.extend_from_slice(&enc_ciphertext[0..COMPACT_NOTE_SIZE]);
|
plaintext.extend_from_slice(&enc_ciphertext[0..COMPACT_NOTE_SIZE]);
|
||||||
let keystream = chacha20.next();
|
assert_eq!(
|
||||||
for i in 0..COMPACT_NOTE_SIZE {
|
ChaCha20Ietf::cipher()
|
||||||
plaintext[i] ^= keystream.as_bytes()[i];
|
.decrypt(
|
||||||
}
|
&mut plaintext,
|
||||||
|
CHACHA20_BLOCK_SIZE + COMPACT_NOTE_SIZE,
|
||||||
|
key.as_bytes(),
|
||||||
|
&[0u8; 12],
|
||||||
|
)
|
||||||
|
.ok()?,
|
||||||
|
CHACHA20_BLOCK_SIZE + COMPACT_NOTE_SIZE
|
||||||
|
);
|
||||||
|
|
||||||
parse_note_plaintext_minus_memo(ivk, cmu, &plaintext)
|
parse_note_plaintext_minus_memo(ivk, cmu, &plaintext[CHACHA20_BLOCK_SIZE..])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to decrypt and validate the given `enc_ciphertext` using the given `ovk`.
|
/// Attempts to decrypt and validate the given `enc_ciphertext` using the given `ovk`.
|
||||||
@ -396,16 +403,13 @@ pub fn try_sapling_output_recovery(
|
|||||||
|
|
||||||
let ock = prf_ock(&ovk, &cv, &cmu, &epk);
|
let ock = prf_ock(&ovk, &cv, &cmu, &epk);
|
||||||
|
|
||||||
let mut op = Vec::with_capacity(OUT_PLAINTEXT_SIZE);
|
let mut op = vec![0; OUT_CIPHERTEXT_SIZE];
|
||||||
chacha20_poly1305_aead::decrypt(
|
assert_eq!(
|
||||||
ock.as_bytes(),
|
ChachaPolyIetf::aead_cipher()
|
||||||
&[0u8; 12],
|
.open_to(&mut op, &out_ciphertext, &[], ock.as_bytes(), &[0u8; 12])
|
||||||
&[],
|
.ok()?,
|
||||||
&out_ciphertext[..OUT_PLAINTEXT_SIZE],
|
OUT_PLAINTEXT_SIZE
|
||||||
&out_ciphertext[OUT_PLAINTEXT_SIZE..],
|
);
|
||||||
&mut op,
|
|
||||||
)
|
|
||||||
.ok()?;
|
|
||||||
|
|
||||||
let pk_d = edwards::Point::<Bls12, _>::read(&op[0..32], &JUBJUB)
|
let pk_d = edwards::Point::<Bls12, _>::read(&op[0..32], &JUBJUB)
|
||||||
.ok()?
|
.ok()?
|
||||||
@ -418,16 +422,19 @@ pub fn try_sapling_output_recovery(
|
|||||||
let shared_secret = sapling_ka_agree(&esk, &pk_d);
|
let shared_secret = sapling_ka_agree(&esk, &pk_d);
|
||||||
let key = kdf_sapling(&shared_secret, &epk);
|
let key = kdf_sapling(&shared_secret, &epk);
|
||||||
|
|
||||||
let mut plaintext = Vec::with_capacity(NOTE_PLAINTEXT_SIZE);
|
let mut plaintext = vec![0; ENC_CIPHERTEXT_SIZE];
|
||||||
chacha20_poly1305_aead::decrypt(
|
assert_eq!(
|
||||||
key.as_bytes(),
|
ChachaPolyIetf::aead_cipher()
|
||||||
&[0u8; 12],
|
.open_to(
|
||||||
&[],
|
&mut plaintext,
|
||||||
&enc_ciphertext[..NOTE_PLAINTEXT_SIZE],
|
&enc_ciphertext,
|
||||||
&enc_ciphertext[NOTE_PLAINTEXT_SIZE..],
|
&[],
|
||||||
&mut plaintext,
|
key.as_bytes(),
|
||||||
)
|
&[0u8; 12]
|
||||||
.ok()?;
|
)
|
||||||
|
.ok()?,
|
||||||
|
NOTE_PLAINTEXT_SIZE
|
||||||
|
);
|
||||||
|
|
||||||
let mut d = [0u8; 11];
|
let mut d = [0u8; 11];
|
||||||
d.copy_from_slice(&plaintext[1..12]);
|
d.copy_from_slice(&plaintext[1..12]);
|
||||||
@ -631,6 +638,13 @@ mod tests {
|
|||||||
let out_ciphertext = ne.encrypt_outgoing_plaintext(&cv, &cmu);
|
let out_ciphertext = ne.encrypt_outgoing_plaintext(&cv, &cmu);
|
||||||
|
|
||||||
assert!(try_sapling_note_decryption(&ivk, epk, &cmu, &enc_ciphertext).is_some());
|
assert!(try_sapling_note_decryption(&ivk, epk, &cmu, &enc_ciphertext).is_some());
|
||||||
|
assert!(try_sapling_compact_note_decryption(
|
||||||
|
&ivk,
|
||||||
|
epk,
|
||||||
|
&cmu,
|
||||||
|
&enc_ciphertext[..COMPACT_NOTE_SIZE]
|
||||||
|
)
|
||||||
|
.is_some());
|
||||||
assert!(try_sapling_output_recovery(
|
assert!(try_sapling_output_recovery(
|
||||||
&ovk,
|
&ovk,
|
||||||
&cv,
|
&cv,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user