red_jubjub/
lib.rs

1// Copyright (C) 2022-2023 Invers (JP) INC.
2// SPDX-License-Identifier: Apache-2.0
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// 	http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#![no_std]
17#![doc = include_str!("../README.md")]
18
19pub mod constant;
20mod hash;
21mod private_key;
22mod public_key;
23mod signature;
24
25use bls_12_381::Fr;
26pub use hash::sapling_hash;
27use jub_jub::{Fp, JubjubAffine, JubjubExtended};
28pub use private_key::SecretKey;
29pub use public_key::PublicKey;
30pub use signature::Signature;
31use zkstd::common::RedDSA;
32
33#[derive(Copy, Clone, Debug, PartialEq, Eq, Default, PartialOrd, Ord)]
34pub struct RedJubjub {}
35
36impl RedDSA for RedJubjub {
37    type Range = Fr;
38
39    type Scalar = Fp;
40
41    type Affine = JubjubAffine;
42
43    type Extended = JubjubExtended;
44}
45
46/// An redjubjub secret key and public key pair.
47#[derive(Copy, Clone, Debug)]
48pub struct Keypair<P: RedDSA> {
49    /// secret key
50    pub secret: SecretKey<P>,
51    /// public key
52    pub public: PublicKey<P>,
53}
54
55impl<P: RedDSA> Keypair<P> {
56    pub fn new(secret: SecretKey<P>) -> Self {
57        let public = secret.to_public_key();
58        Self { secret, public }
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65    use jub_jub::Fp;
66    use rand_core::OsRng;
67    use zkstd::common::{Group, SigUtils};
68
69    #[test]
70    fn sig_utils() {
71        let randomness = OsRng;
72        let msg = b"test";
73        let secret = SecretKey::<RedJubjub>(Fp::random(OsRng));
74        let sig = secret.sign(msg, randomness);
75        let pub_key = secret.to_public_key();
76
77        let sig_bytes = sig.to_bytes();
78        let sig_back = Signature::from_bytes(sig_bytes).unwrap();
79        assert_eq!(sig, sig_back);
80
81        let pub_key_bytes = pub_key.to_bytes();
82        let pub_key_back = PublicKey::from_bytes(pub_key_bytes).unwrap();
83        assert_eq!(pub_key, pub_key_back);
84
85        let secret_bytes = secret.to_bytes();
86        let secret_back = SecretKey::from_bytes(secret_bytes).unwrap();
87        assert_eq!(secret, secret_back);
88    }
89
90    #[test]
91    fn signature_test() {
92        for _ in 0..1000 {
93            let msg = b"test";
94            let wrong_msg = b"tes";
95            let randomness = OsRng;
96
97            let priv_key = SecretKey::<RedJubjub>(Fp::random(OsRng));
98            let sig = priv_key.sign(msg, randomness);
99            let pub_key = priv_key.to_public_key();
100
101            assert!(pub_key.validate(msg, sig));
102            assert!(!pub_key.validate(wrong_msg, sig));
103        }
104    }
105
106    #[test]
107    fn rerandomize_test() {
108        for _ in 0..1000 {
109            let msg = b"test";
110            let wrong_msg = b"tes";
111
112            let priv_key = SecretKey::<RedJubjub>(Fp::random(OsRng));
113            let pub_key = priv_key.to_public_key();
114
115            // randomization
116            let randomize = Fp::random(OsRng);
117            let randomize_priv_key = priv_key.randomize_private(randomize);
118            let randomize_pub_key = pub_key.randomize_public(randomize);
119            let sig = randomize_priv_key.sign(msg, OsRng);
120
121            assert!(randomize_pub_key.validate(msg, sig));
122            assert!(!randomize_pub_key.validate(wrong_msg, sig));
123        }
124    }
125}