mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-12 01:55:48 +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"
|
||||
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]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.3"
|
||||
@ -132,6 +124,19 @@ name = "crossbeam"
|
||||
version = "0.3.2"
|
||||
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]]
|
||||
name = "digest"
|
||||
version = "0.7.2"
|
||||
@ -508,7 +513,7 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"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)",
|
||||
"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",
|
||||
"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)",
|
||||
@ -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.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 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 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.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"
|
||||
|
@ -7,6 +7,7 @@ authors = [
|
||||
|
||||
[dependencies]
|
||||
byteorder = "1"
|
||||
crypto_api_chachapoly = "0.1"
|
||||
ff = { path = "../ff" }
|
||||
hex = "0.3"
|
||||
lazy_static = "1"
|
||||
@ -18,7 +19,3 @@ sha2 = "0.8"
|
||||
[dependencies.blake2-rfc]
|
||||
git = "https://github.com/gtank/blake2-rfc"
|
||||
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 byteorder;
|
||||
extern crate chacha20_poly1305_aead;
|
||||
extern crate crypto_api_chachapoly;
|
||||
extern crate ff;
|
||||
extern crate hex;
|
||||
extern crate pairing;
|
||||
|
@ -1,6 +1,6 @@
|
||||
use blake2_rfc::blake2b::{Blake2b, Blake2bResult};
|
||||
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 pairing::bls12_381::{Bls12, Fr};
|
||||
use rand::{OsRng, Rng};
|
||||
@ -240,19 +240,14 @@ impl SaplingNoteEncryption {
|
||||
input.extend_from_slice(&self.memo.0);
|
||||
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];
|
||||
output[0..NOTE_PLAINTEXT_SIZE].copy_from_slice(&ciphertext);
|
||||
output[NOTE_PLAINTEXT_SIZE..ENC_CIPHERTEXT_SIZE].copy_from_slice(&tag);
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.seal_to(&mut output, &input, &[], &key.as_bytes(), &[0u8; 12])
|
||||
.unwrap(),
|
||||
ENC_CIPHERTEXT_SIZE
|
||||
);
|
||||
|
||||
output
|
||||
}
|
||||
|
||||
@ -263,23 +258,26 @@ impl SaplingNoteEncryption {
|
||||
) -> [u8; OUT_CIPHERTEXT_SIZE] {
|
||||
let key = prf_ock(&self.ovk, &cv, &cmu, &self.epk);
|
||||
|
||||
let mut input = [0u8; OUT_PLAINTEXT_SIZE];
|
||||
self.note.pk_d.write(&mut input[0..32]).unwrap();
|
||||
let mut buf = [0u8; OUT_CIPHERTEXT_SIZE];
|
||||
self.note.pk_d.write(&mut buf[0..32]).unwrap();
|
||||
self.esk
|
||||
.into_repr()
|
||||
.write_le(&mut input[32..OUT_PLAINTEXT_SIZE])
|
||||
.write_le(&mut buf[32..OUT_PLAINTEXT_SIZE])
|
||||
.unwrap();
|
||||
|
||||
let mut buffer = Vec::with_capacity(OUT_PLAINTEXT_SIZE);
|
||||
let tag =
|
||||
chacha20_poly1305_aead::encrypt(key.as_bytes(), &[0u8; 12], &[], &input, &mut buffer)
|
||||
.unwrap();
|
||||
|
||||
let mut output = [0u8; OUT_CIPHERTEXT_SIZE];
|
||||
output[0..OUT_PLAINTEXT_SIZE].copy_from_slice(&buffer);
|
||||
output[OUT_PLAINTEXT_SIZE..OUT_CIPHERTEXT_SIZE].copy_from_slice(&tag[..]);
|
||||
|
||||
output
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.seal(
|
||||
&mut buf,
|
||||
OUT_PLAINTEXT_SIZE,
|
||||
&[],
|
||||
key.as_bytes(),
|
||||
&[0u8; 12]
|
||||
)
|
||||
.unwrap(),
|
||||
OUT_CIPHERTEXT_SIZE
|
||||
);
|
||||
buf
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,16 +327,19 @@ pub fn try_sapling_note_decryption(
|
||||
let shared_secret = sapling_ka_agree(ivk, epk);
|
||||
let key = kdf_sapling(&shared_secret, &epk);
|
||||
|
||||
let mut plaintext = Vec::with_capacity(NOTE_PLAINTEXT_SIZE);
|
||||
chacha20_poly1305_aead::decrypt(
|
||||
key.as_bytes(),
|
||||
&[0u8; 12],
|
||||
&[],
|
||||
&enc_ciphertext[..NOTE_PLAINTEXT_SIZE],
|
||||
&enc_ciphertext[NOTE_PLAINTEXT_SIZE..],
|
||||
&mut plaintext,
|
||||
)
|
||||
.ok()?;
|
||||
let mut plaintext = vec![0; ENC_CIPHERTEXT_SIZE];
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.open_to(
|
||||
&mut plaintext,
|
||||
&enc_ciphertext,
|
||||
&[],
|
||||
key.as_bytes(),
|
||||
&[0u8; 12]
|
||||
)
|
||||
.ok()?,
|
||||
NOTE_PLAINTEXT_SIZE
|
||||
);
|
||||
|
||||
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 key = kdf_sapling(&shared_secret, &epk);
|
||||
|
||||
let mut chacha20 = ChaCha20::new(key.as_bytes(), &[0u8; 12]);
|
||||
// Skip over Poly1305 keying output
|
||||
chacha20.next();
|
||||
|
||||
let mut plaintext = Vec::with_capacity(COMPACT_NOTE_SIZE);
|
||||
// Prefix plaintext with 64 zero-bytes to skip over Poly1305 keying output
|
||||
const CHACHA20_BLOCK_SIZE: usize = 64;
|
||||
let mut plaintext = Vec::with_capacity(CHACHA20_BLOCK_SIZE + COMPACT_NOTE_SIZE);
|
||||
plaintext.extend_from_slice(&[0; CHACHA20_BLOCK_SIZE]);
|
||||
plaintext.extend_from_slice(&enc_ciphertext[0..COMPACT_NOTE_SIZE]);
|
||||
let keystream = chacha20.next();
|
||||
for i in 0..COMPACT_NOTE_SIZE {
|
||||
plaintext[i] ^= keystream.as_bytes()[i];
|
||||
}
|
||||
assert_eq!(
|
||||
ChaCha20Ietf::cipher()
|
||||
.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`.
|
||||
@ -396,16 +403,13 @@ pub fn try_sapling_output_recovery(
|
||||
|
||||
let ock = prf_ock(&ovk, &cv, &cmu, &epk);
|
||||
|
||||
let mut op = Vec::with_capacity(OUT_PLAINTEXT_SIZE);
|
||||
chacha20_poly1305_aead::decrypt(
|
||||
ock.as_bytes(),
|
||||
&[0u8; 12],
|
||||
&[],
|
||||
&out_ciphertext[..OUT_PLAINTEXT_SIZE],
|
||||
&out_ciphertext[OUT_PLAINTEXT_SIZE..],
|
||||
&mut op,
|
||||
)
|
||||
.ok()?;
|
||||
let mut op = vec![0; OUT_CIPHERTEXT_SIZE];
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.open_to(&mut op, &out_ciphertext, &[], ock.as_bytes(), &[0u8; 12])
|
||||
.ok()?,
|
||||
OUT_PLAINTEXT_SIZE
|
||||
);
|
||||
|
||||
let pk_d = edwards::Point::<Bls12, _>::read(&op[0..32], &JUBJUB)
|
||||
.ok()?
|
||||
@ -418,16 +422,19 @@ pub fn try_sapling_output_recovery(
|
||||
let shared_secret = sapling_ka_agree(&esk, &pk_d);
|
||||
let key = kdf_sapling(&shared_secret, &epk);
|
||||
|
||||
let mut plaintext = Vec::with_capacity(NOTE_PLAINTEXT_SIZE);
|
||||
chacha20_poly1305_aead::decrypt(
|
||||
key.as_bytes(),
|
||||
&[0u8; 12],
|
||||
&[],
|
||||
&enc_ciphertext[..NOTE_PLAINTEXT_SIZE],
|
||||
&enc_ciphertext[NOTE_PLAINTEXT_SIZE..],
|
||||
&mut plaintext,
|
||||
)
|
||||
.ok()?;
|
||||
let mut plaintext = vec![0; ENC_CIPHERTEXT_SIZE];
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.open_to(
|
||||
&mut plaintext,
|
||||
&enc_ciphertext,
|
||||
&[],
|
||||
key.as_bytes(),
|
||||
&[0u8; 12]
|
||||
)
|
||||
.ok()?,
|
||||
NOTE_PLAINTEXT_SIZE
|
||||
);
|
||||
|
||||
let mut d = [0u8; 11];
|
||||
d.copy_from_slice(&plaintext[1..12]);
|
||||
@ -631,6 +638,13 @@ mod tests {
|
||||
let out_ciphertext = ne.encrypt_outgoing_plaintext(&cv, &cmu);
|
||||
|
||||
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(
|
||||
&ovk,
|
||||
&cv,
|
||||
|
Loading…
x
Reference in New Issue
Block a user