Skip to content

Commit

Permalink
test
Browse files Browse the repository at this point in the history
  • Loading branch information
heliannuuthus committed Aug 11, 2024
1 parent 75eb3ca commit 45e39b8
Show file tree
Hide file tree
Showing 4 changed files with 259 additions and 154 deletions.
68 changes: 42 additions & 26 deletions sm2/src/pke.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
use core::cmp::min;

use crate::AffinePoint;
use crate::U32;

#[cfg(feature = "alloc")]
use alloc::vec;
use alloc::vec::Vec;
use elliptic_curve::bigint::Integer;
use elliptic_curve::bigint::Uint;
use elliptic_curve::bigint::U256;

use elliptic_curve::pkcs8::der::asn1::UintRef;
use elliptic_curve::pkcs8::der::Decode;
use elliptic_curve::pkcs8::der::DecodeValue;
use elliptic_curve::pkcs8::der::Encode;
use elliptic_curve::pkcs8::der::Length;
use elliptic_curve::pkcs8::der::Reader;
use elliptic_curve::pkcs8::der::Sequence;
use elliptic_curve::pkcs8::der::Writer;
use elliptic_curve::pkcs8::Version;
use elliptic_curve::FieldBytesEncoding;

use elliptic_curve::{
array::Array,
pkcs8::der::{asn1::OctetStringRef, EncodeValue},
sec1::ToEncodedPoint,
Result,
Expand All @@ -36,31 +33,49 @@ pub use self::{decrypting::DecryptingKey, encrypting::EncryptingKey};
pub struct Cipher<'a> {
x: &'a [u8],
y: &'a [u8],
sm3: &'a [u8],
secret: &'a [u8],
digest: &'a [u8],
cipher: &'a [u8],
}

impl<'a> Encode for Cipher<'a> {
fn encoded_len(&self) -> elliptic_curve::pkcs8::der::Result<Length> {
Length::new((self.x.len() + self.y.len() + self.sm3.len() + self.secret.len()) as u16)
.encoded_len()
}
impl<'a> Sequence<'a> for Cipher<'a> {}

fn encode(&self, writer: &mut impl Writer) -> elliptic_curve::pkcs8::der::Result<()> {
UintRef::new(self.x)?.encode(writer)?;
UintRef::new(self.y)?.encode(writer)?;
OctetStringRef::new(self.sm3)?.encode(writer)?;
OctetStringRef::new(self.secret)?.encode(writer)?;
impl<'a> EncodeValue for Cipher<'a> {
fn value_len(&self) -> elliptic_curve::pkcs8::der::Result<Length> {
UintRef::new(&self.x)?.encoded_len()?
+ UintRef::new(&self.y)?.encoded_len()?
+ OctetStringRef::new(&self.digest)?.encoded_len()?
+ OctetStringRef::new(&self.cipher)?.encoded_len()?
}
fn encode_value(&self, writer: &mut impl Writer) -> elliptic_curve::pkcs8::der::Result<()> {
UintRef::new(&self.x)?.encode(writer)?;
UintRef::new(&self.y)?.encode(writer)?;
OctetStringRef::new(&self.digest)?.encode(writer)?;
OctetStringRef::new(&self.cipher)?.encode(writer)?;
Ok(())
}
}

impl<'a> Decode<'a> for Cipher<'a> {
impl<'a> DecodeValue<'a> for Cipher<'a> {
type Error = elliptic_curve::pkcs8::der::Error;

fn decode<R: Reader<'a>>(decoder: &mut R) -> core::result::Result<Self, Self::Error> {}
fn decode_value<R: Reader<'a>>(
decoder: &mut R,
header: elliptic_curve::pkcs8::der::Header,
) -> core::result::Result<Self, Self::Error> {
decoder.read_nested(header.length, |nr| {
let x = UintRef::decode(nr)?.as_bytes();
let y = UintRef::decode(nr)?.as_bytes();
let digest = OctetStringRef::decode(nr)?.into();
let cipher = OctetStringRef::decode(nr)?.into();
Ok(Cipher {
x,
y,
digest,
cipher,
})
})
}
}

#[derive(Clone, Copy, Debug)]
pub enum Mode {
C1C2C3,
Expand All @@ -72,13 +87,14 @@ fn kdf(hasher: &mut dyn DynDigest, kpb: AffinePoint, c2: &mut [u8]) -> Result<()
let mut ct: i32 = 0x00000001;
let mut offset = 0;
let digest_size = hasher.output_size();
let mut ha = vec![0u8; hasher.output_size()];
let mut ha = vec![0u8; digest_size];
let encode_point = kpb.to_encoded_point(false);

while offset < klen {
hasher.update(&encode_point.x().unwrap());
hasher.update(&encode_point.y().unwrap());
hasher.update(encode_point.x().unwrap());
hasher.update(encode_point.y().unwrap());
hasher.update(&ct.to_be_bytes());

hasher
.finalize_into_reset(&mut ha)
.map_err(|_e| elliptic_curve::Error)?;
Expand Down
122 changes: 72 additions & 50 deletions sm2/src/pke/decrypting.rs
Original file line number Diff line number Diff line change
@@ -1,50 +1,43 @@
use core::fmt::{self, Debug};

use crate::arithmetic::field::FieldElement;
use crate::{AffinePoint, EncodedPoint, FieldBytes, NonZeroScalar, PublicKey, Scalar, SecretKey};
use alloc::boxed::Box;

use alloc::vec::Vec;
use elliptic_curve::ops::Reduce;
use elliptic_curve::pkcs8::der::Decode;
use elliptic_curve::sec1::FromEncodedPoint;
use elliptic_curve::subtle::{Choice, ConstantTimeEq};
use elliptic_curve::Error;
use elliptic_curve::{
bigint::U256,
sec1::{ToEncodedPoint, UncompressedPoint},
Group, Result,
};
use elliptic_curve::{bigint::U256, sec1::ToEncodedPoint, Group, Result};
use primeorder::PrimeField;

use sm3::digest::DynDigest;
use sm3::{Digest, Sm3};

use super::encrypting::EncryptingKey;
use super::{kdf, vec, Cipher, Mode};

#[derive(Clone)]
pub struct DecryptingKey {
secret_scalar: NonZeroScalar,
encrytingKey: EncryptingKey,
encryting_key: EncryptingKey,
mode: Mode,
digest: Box<dyn DynDigest + Send + Sync>,
}

impl DecryptingKey {
pub fn new(secret_key: SecretKey) -> Self {
Self::new_with_mode(secret_key.to_nonzero_scalar(), Mode::C1C2C3)
Self::new_with_mode(secret_key.to_nonzero_scalar(), Mode::C1C3C2)
}

pub fn new_with_mode(secret_scalar: NonZeroScalar, mode: Mode) -> Self {
Self::new_with_mode_and_hash::<Sm3>(secret_scalar, mode)
}

pub fn new_with_mode_and_hash<D: 'static + Digest + DynDigest + Send + Sync>(
secret_scalar: NonZeroScalar,
mode: Mode,
) -> Self {
Self {
secret_scalar,
encrytingKey: EncryptingKey::new_with_mode_and_hash::<D>(
encryting_key: EncryptingKey::new_with_mode(
PublicKey::from_secret_scalar(&secret_scalar),
mode,
),
mode,
digest: Box::new(D::new()),
}
}

Expand All @@ -62,7 +55,7 @@ impl DecryptingKey {

/// Create a signing key from a non-zero scalar.
pub fn from_nonzero_scalar(secret_scalar: NonZeroScalar) -> Result<Self> {
Ok(Self::new_with_mode(secret_scalar, Mode::C1C2C3))
Ok(Self::new_with_mode(secret_scalar, Mode::C1C3C2))
}

/// Serialize as bytes.
Expand All @@ -81,47 +74,76 @@ impl DecryptingKey {
&self.secret_scalar
}

/// Get the [`VerifyingKey`] which corresponds to this [`SigningKey`].
/// Get the [`EncryptingKey`] which corresponds to this [`DecryptingKey`].
pub fn encrypting_key(&self) -> &EncryptingKey {
&self.encrytingKey
&self.encryting_key
}

/// Decrypt inplace
pub fn decrypt(&self, ciphertext: &mut [u8]) -> Result<Vec<u8>> {
self.decrypt_digest::<Sm3>(ciphertext)
}
/// Decrypt inplace
pub fn decrypt_digest<D>(&self, ciphertext: &mut [u8]) -> Result<Vec<u8>>
where
D: 'static + Digest + DynDigest + Send + Sync,
{
let mut digest = D::new();
decrypt(&self.secret_scalar, self.mode, &mut digest, ciphertext)
}

pub fn decrypt_asna1(&self, ciphertext: &[u8]) -> Result<Vec<u8>> {
self.decrypt_asna1_digest::<Sm3>(ciphertext)
}

/// Decrypt inplace
pub fn decrypt(&mut self, ciphertext: &mut [u8]) -> Result<Vec<u8>> {
decrypt(
&self.secret_scalar,
self.mode,
&mut *self.digest,
ciphertext,
)
pub fn decrypt_asna1_digest<D>(&self, ciphertext: &[u8]) -> Result<Vec<u8>>
where
D: 'static + Digest + DynDigest + Send + Sync,
{
let cipher =
Cipher::from_der(&ciphertext).map_err(|e| elliptic_curve::pkcs8::Error::from(e))?;

let mut cipher = match self.mode {
Mode::C1C2C3 => [&[0x04], cipher.x, cipher.y, cipher.cipher, cipher.digest].concat(),
Mode::C1C3C2 => [&[0x04], cipher.x, cipher.y, cipher.digest, cipher.cipher].concat(),
};

Ok(self.decrypt_digest::<D>(&mut cipher)?)
}
}

fn decrypt_asna1(
secret_scalar: &Scalar,
mode: Mode,
hasher: &mut dyn DynDigest,
cipher: &mut [u8],
) -> Result<Vec<u8>> {

let digest_size = hasher.output_size();
let (x, cipher) = cipher.split_at(32);
let (y, cipher) = cipher.split_at(32);
let (sm3, cipher) = match mode {
Mode::C1C2C3 => cipher.split_at(digest_size),
Mode::C1C3C2 => cipher.split_at(cipher.len() - digest_size),
};
Cipher {
x: x.into(),
y,
sm3,
secret: cipher,
//
// Other trait impls
//

impl AsRef<EncryptingKey> for DecryptingKey {
fn as_ref(&self) -> &EncryptingKey {
&self.encryting_key
}
.to_der()
.map_err(|e| Error)
}

impl ConstantTimeEq for DecryptingKey {
fn ct_eq(&self, other: &Self) -> Choice {
self.secret_scalar.ct_eq(&other.secret_scalar)
}
}

impl Debug for DecryptingKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("DecryptingKey")
.field("private_key", &self.secret_scalar.as_ref())
.field("encrypting_key", &self.encrypting_key())
.finish_non_exhaustive()
}
}

let plain = decrypt(secret_scalar, mode, hasher, cipher)?;
/// Constant-time comparison
impl Eq for DecryptingKey {}
impl PartialEq for DecryptingKey {
fn eq(&self, other: &DecryptingKey) -> bool {
self.ct_eq(other).into()
}
}

fn decrypt(
Expand Down
Loading

0 comments on commit 45e39b8

Please sign in to comment.