Skip to content

Commit

Permalink
V4.0.1
Browse files Browse the repository at this point in the history
Fix schnorr vrf verification.
  • Loading branch information
mrtnetwork committed Jan 23, 2025
1 parent 5e36e6a commit cf834bb
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 16 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 4.0.1

- Fix schnorr vrf verification.

## 4.0.0

- Minimum required Dart SDK version updated to 3.3.
Expand Down
18 changes: 14 additions & 4 deletions lib/crypto/crypto/schnorrkel/keys/keys.dart
Original file line number Diff line number Diff line change
Expand Up @@ -606,10 +606,7 @@ class SchnorrkelSecretKey {
{GenerateRandom? nonceGenerator,
bool kusamaVRF = true,
MerlinTranscript? verifyScript}) {
final publicHashPoint = publicKey().vrfHash(script);
final keyBig = BigintUtils.fromBytes(key(), byteOrder: Endian.little);
final mul = publicHashPoint * keyBig;
final vrf = VRFInOut._(publicHashPoint.toBytes(), mul.toBytes());
final vrf = vrfInOut(script);
return Tuple(
vrf,
dleqProve(vrf,
Expand All @@ -618,6 +615,19 @@ class SchnorrkelSecretKey {
verifyScript: verifyScript));
}

/// This function computes the VRF (Verifiable Random Function) input and output
/// using the provided `MerlinTranscript` as the cryptographic context.
///
/// The process involves hashing a transcript with the public key to generate
/// a curve point, multiplying this point with the private key, and returning
/// the corresponding VRF input and output.
VRFInOut vrfInOut(MerlinTranscript script) {
final publicHashPoint = publicKey().vrfHash(script);
final keyBig = BigintUtils.fromBytes(key(), byteOrder: Endian.little);
final mul = publicHashPoint * keyBig;
return VRFInOut._(publicHashPoint.toBytes(), mul.toBytes());
}

/// Generates a Discrete Logarithm Equality Proof (DLEQ) for a Verifiable Random Function (VRF) output.
///
/// This method generates a DLEQ proof for a given VRF output, ensuring the equality of discrete logarithms of
Expand Down
19 changes: 11 additions & 8 deletions lib/layout/utils/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,26 @@ class LayoutSerializationUtils {
return const SubstrateScaleCUintEncoder().encode(value.toString());
}

static Tuple<int, BigInt> decodeLength(List<int> bytes, {bool sign = false}) {
switch (bytes[0] & 0x03) {
static Tuple<int, BigInt> decodeLength(List<int> bytes,
{bool sign = false, int offset = 0}) {
final byte = bytes[offset];

switch (byte & 0x03) {
case 0x00:
return Tuple(1, BigInt.from(bytes[0]) >> 2);
return Tuple(1, BigInt.from(byte) >> 2);
case 0x01:
final val = BigintUtils.fromBytes(bytes.sublist(0, 2),
final val = BigintUtils.fromBytes(bytes.sublist(offset, offset + 2),
sign: sign, byteOrder: Endian.little);
return Tuple(2, val >> 2);
case 0x02:
final val = BigintUtils.fromBytes(bytes.sublist(0, 4),
final val = BigintUtils.fromBytes(bytes.sublist(offset, offset + 4),
sign: sign, byteOrder: Endian.little);
return Tuple(4, val >> 2);
default:
final int offset = (bytes[0] >> 2) + 5;
final val = BigintUtils.fromBytes(bytes.sublist(1, offset),
final int o = (byte >> 2) + 5;
final val = BigintUtils.fromBytes(bytes.sublist(offset + 1, offset + o),
sign: sign, byteOrder: Endian.little);
return Tuple(offset, val);
return Tuple(o, val);
}
}

Expand Down
7 changes: 4 additions & 3 deletions lib/signer/substrate/core/verifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ abstract class BaseSubstrateVerifier {
}
}
factory BaseSubstrateVerifier.fromSubstrate(Substrate substrate) {
final publicKey = substrate.publicKey.compressed;
switch (substrate.coinConf.type) {
case EllipticCurveTypes.ed25519:
return SubstrateED25519Verifier.fromKeyBytes(substrate.priveKey.raw);
return SubstrateED25519Verifier.fromKeyBytes(publicKey);
case EllipticCurveTypes.secp256k1:
return SubstrateEcdsaVerifier.fromKeyBytes(substrate.priveKey.raw);
return SubstrateEcdsaVerifier.fromKeyBytes(publicKey);
default:
return SubstrateSr25519Verifier.fromKeyBytes(substrate.priveKey.raw);
return SubstrateSr25519Verifier.fromKeyBytes(publicKey);
}
}
}
26 changes: 26 additions & 0 deletions lib/signer/substrate/signers/substrate_sr25519.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,32 @@ class SubstrateSr25519Signer implements BaseSubstrateSigner {
}
return vrfResult;
}

bool vrfVerify(List<int> message, List<int> vrfSign,
{List<int>? context, List<int>? extra}) {
if (vrfSign.length != _SubstrateSr25519SignerConst.vrfResultLength &&
vrfSign.length != SchnorrkelKeyCost.vrfProofLength) {
throw ArgumentException(
"Invalid VrfSign bytes length. excepted: ${_SubstrateSr25519SignerConst.vrfResultLength}, ${SchnorrkelKeyCost.vrfProofLength} got: ${vrfSign.length} ");
}
final MerlinTranscript script =
_SubstrateSr25519SignerUtils.substrateVrfSignScript(message, context);
VRFPreOut output;
VRFProof proof;
if (vrfSign.length == SchnorrkelKeyCost.vrfProofLength) {
output = _signer.vrfInOut(script).toVRFPreOut();
proof = VRFProof.fromBytes(vrfSign);
} else {
output = VRFPreOut(vrfSign.sublist(0, SchnorrkelKeyCost.vrfPreOutLength));
proof = VRFProof.fromBytes(
vrfSign.sublist(SchnorrkelKeyCost.vrfPreOutLength));
}
return _signer.publicKey().vrfVerify(
_SubstrateSr25519SignerUtils.substrateVrfSignScript(message, context),
output,
proof,
verifyScript: _SubstrateSr25519SignerUtils.vrfScript(extra: extra));
}
}

/// Class representing an Substrate SR25519 Verifier for signature verification.
Expand Down
8 changes: 8 additions & 0 deletions lib/utils/string/string.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ class StringUtils {
return value;
}

/// add the '0x' prefix to a hexadecimal string if it exists.
static String add0x(String value) {
if (value.toLowerCase().startsWith("0x")) {
return value;
}
return "0x$value";
}

/// Encodes the given [value] string into a list of bytes using the specified [type].
///
/// The [type] parameter determines the encoding type to use, with UTF-8 being the default.
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: blockchain_utils
description: Comprehensive Crypto & Blockchain Toolkit, Pure Dart, Cross-Platform, Encoding, Cryptography, Addresses, Mnemonics, & More.
version: 4.0.0
version: 4.0.1
homepage: "https://github.com/mrtnetwork/blockchain_utils"
repository: "https://github.com/mrtnetwork/blockchain_utils"
Author: [email protected]
Expand Down

0 comments on commit cf834bb

Please sign in to comment.