Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Implementation and secure usage of cryptographic primitives including ECDSA, BLS, Schnorr signatures, key derivation, secret sharing, and constant-time operations. Provides guidance for secure cryptographic implementations in blockchain applications.
.claude/skills/a5c-ai-crypto-primitives/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 262% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 115% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 153% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 123% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 65% | 0% |
Expert implementation and usage of cryptographic primitives for blockchain and security applications.
Standard Ethereum signature scheme:
javascriptimport { secp256k1 } from '@noble/curves/secp256k1'; import { keccak_256 } from '@noble/hashes/sha3'; // Sign message const messageHash = keccak_256(message); const signature = secp256k1.sign(messageHash, privateKey); // Verify signature const isValid = secp256k1.verify(signature, messageHash, publicKey); // Recover public key from signature (Ethereum style) const recoveredPubKey = signature.recoverPublicKey(messageHash);
Aggregatable signatures for validator sets:
javascriptimport { bls12_381 } from '@noble/curves/bls12-381'; // Sign with BLS const signature = bls12_381.sign(message, privateKey); // Verify const isValid = bls12_381.verify(signature, message, publicKey); // Aggregate signatures const aggregatedSig = bls12_381.aggregateSignatures([sig1, sig2, sig3]); const aggregatedPubKeys = bls12_381.aggregatePublicKeys([pk1, pk2, pk3]); const isValidAgg = bls12_381.verify(aggregatedSig, message, aggregatedPubKeys);
BIP-340 compliant Schnorr signatures:
javascriptimport { schnorr } from '@noble/curves/secp256k1'; // Sign (returns 64-byte signature) const signature = schnorr.sign(messageHash, privateKey); // Verify const isValid = schnorr.verify(signature, messageHash, publicKey);
javascriptimport { HDKey } from '@scure/bip32'; import { mnemonicToSeedSync } from '@scure/bip39'; // From mnemonic to seed const seed = mnemonicToSeedSync(mnemonic); // Create HD wallet const hdkey = HDKey.fromMasterSeed(seed); // Derive path (BIP-44 for Ethereum) // m/44'/60'/0'/0/0 const child = hdkey .derive("m/44'/60'/0'/0") .deriveChild(0); const privateKey = child.privateKey; const publicKey = child.publicKey;
javascriptimport { generateMnemonic, validateMnemonic } from '@scure/bip39'; import { wordlist } from '@scure/bip39/wordlists/english'; // Generate new mnemonic (128 bits = 12 words, 256 bits = 24 words) const mnemonic = generateMnemonic(wordlist, 256); // Validate mnemonic const isValid = validateMnemonic(mnemonic, wordlist);
javascriptimport { split, combine } from 'shamir-secret-sharing'; // Split secret into 5 shares, requiring 3 to reconstruct const shares = await split(secretBytes, 5, 3); // Reconstruct with any 3 shares const reconstructed = await combine([shares[0], shares[2], shares[4]]);
javascript// Commitments allow verification without revealing secret const { shares, commitments } = feldmanVSS.split(secret, n, t); // Verify a share const isValidShare = feldmanVSS.verifyShare(share, commitments);
javascriptimport { keccak_256 } from '@noble/hashes/sha3'; // Ethereum address from public key const publicKeyHash = keccak_256(publicKey.slice(1)); // Remove 0x04 prefix const address = '0x' + publicKeyHash.slice(-20).toString('hex');
javascript// Poseidon hash (used in ZK circuits) import { poseidon } from '@iden3/js-crypto'; const hash = poseidon([input1, input2, input3]); // MiMC hash import { mimcSponge } from 'circomlib'; const hash = mimcSponge.multiHash([input1, input2], key, numOutputs);
javascript// commit(m, r) = g^m * h^r // Hiding: cannot determine m from commitment // Binding: cannot find m', r' where commit(m, r) = commit(m', r') function pedersenCommit(m, r, g, h) { return g.multiply(m).add(h.multiply(r)); } // Verify commitment function verifyCommitment(commitment, m, r, g, h) { const expected = pedersenCommit(m, r, g, h); return commitment.equals(expected); }
javascript// Simple commit-reveal scheme function commit(value, nonce) { return keccak256(abi.encodePacked(value, nonce)); } function reveal(commitment, value, nonce) { return commitment === keccak256(abi.encodePacked(value, nonce)); }
javascript// BAD: Timing attack vulnerable function compareInsecure(a, b) { return a === b; // Short-circuits on first mismatch } // GOOD: Constant-time comparison function compareSecure(a, b) { if (a.length !== b.length) return false; let diff = 0; for (let i = 0; i < a.length; i++) { diff |= a[i] ^ b[i]; } return diff === 0; }
javascriptimport { timingSafeEqual } from 'crypto'; // Use built-in constant-time comparison const isEqual = timingSafeEqual(Buffer.from(a), Buffer.from(b));
javascriptimport { randomBytes } from '@noble/hashes/utils'; // Generate secure random bytes const privateKey = randomBytes(32); // For browser environments const array = new Uint8Array(32); crypto.getRandomValues(array);
solidity// Request randomness on-chain function requestRandomness() external returns (uint256 requestId) { return COORDINATOR.requestRandomWords( keyHash, subscriptionId, requestConfirmations, callbackGasLimit, numWords ); } function fulfillRandomWords(uint256, uint256[] memory randomWords) internal override { // Use randomWords[0] for provably fair randomness }
This skill integrates with:
cryptographic-protocol-implementation.js - Full protocol designhd-wallet-implementation.js - Wallet key managementmulti-signature-wallet.js - Multi-sig schemesthreshold-signature-scheme.js - TSS implementationzk-circuit-development.js - ZK-friendly primitives| Library | Purpose | URL | |---------|---------|-----| | @noble/curves | Elliptic curves (secp256k1, ed25519, BLS12-381) | noble-curves | | @noble/hashes | Hash functions (SHA, Keccak, BLAKE) | noble-hashes | | @scure/bip32 | HD key derivation | scure-bip32 | | @scure/bip39 | Mnemonic generation | scure-bip39 | | libsodium | General-purpose crypto | libsodium.js | | circomlibjs | ZK-friendly crypto | circomlibjs |
agents/crypto-engineer/AGENT.md - Cryptographic implementation expertskills/zk-circuits/SKILL.md - Zero-knowledge circuitsreferences.md - External cryptographic references| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 7,489 | 14,937 | +99% | 1 | 1 | 0% | 1,422 | 5,151 | +262% | 0 | 0 | — |
case-02 | fail→fail | 7,381 | 10,189 | +38% | 1 | 1 | 0% | 1,370 | 4,310 | +215% | 0 | 0 | — |
case-03 | fail→pass | 8,610 | 5,964 | -31% | 1 | 1 | 0% | 1,628 | 3,497 | +115% | 0 | 0 | — |
case-04 | fail→fail | 8,615 | 4,954 | -42% | 1 | 1 | 0% | 1,654 | 3,339 | +102% | 0 | 0 | — |
case-05 | pass→pass | 10,633 | 4,417 | -58% | 1 | 1 | 0% | 1,921 | 3,176 | +65% | 0 | 0 | — |
case-06 | fail→pass | 7,191 | 4,991 | -31% | 1 | 1 | 0% | 1,281 | 3,238 | +153% | 0 | 0 | — |
case-07 | pass→pass | 10,728 | 2,646 | -75% | 1 | 1 | 0% | 2,059 | 2,833 | +38% | 0 | 0 | — |
case-08 | fail→fail | 8,320 | 5,700 | -31% | 1 | 1 | 0% | 1,624 | 3,325 | +105% | 0 | 0 | — |
case-09 | fail→pass | 9,601 | 9,113 | -5% | 1 | 1 | 0% | 1,867 | 4,164 | +123% | 0 | 0 | — |
case-10 | fail→fail | 16,102 | 9,427 | -41% | 1 | 1 | 0% | 2,608 | 4,432 | +70% | 0 | 0 | — |
case-11 | fail→fail | 13,959 | 9,869 | -29% | 1 | 1 | 0% | 2,848 | 4,425 | +55% | 0 | 0 | — |
case-12 | fail→fail | 13,418 | 5,729 | -57% | 1 | 1 | 0% | 2,070 | 3,476 | +68% | 0 | 0 | — |
case-13 | fail→fail | 13,543 | 6,094 | -55% | 1 | 1 | 0% | 2,179 | 3,534 | +62% | 0 | 0 | — |
case-14 | fail→fail | 11,831 | 10,133 | -14% | 1 | 1 | 0% | 2,315 | 4,440 | +92% | 0 | 0 | — |
case-15 | fail→fail | 13,823 | 9,797 | -29% | 1 | 1 | 0% | 2,794 | 4,386 | +57% | 0 | 0 | — |
case-16 | fail→fail | 4,010 | 2,687 | -33% | 1 | 1 | 0% | 785 | 2,836 | +261% | 0 | 0 | — |
case-17 | fail→fail | 7,620 | 4,345 | -43% | 1 | 1 | 0% | 1,515 | 3,263 | +115% | 0 | 0 | — |
case-18 | fail→fail | 13,685 | 10,238 | -25% | 1 | 1 | 0% | 2,607 | 4,155 | +59% | 0 | 0 | — |
case-19 | fail→fail | 15,348 | 9,361 | -39% | 1 | 1 | 0% | 2,536 | 4,266 | +68% | 0 | 0 | — |
case-20 | fail→fail | 8,536 | 5,769 | -32% | 1 | 1 | 0% | 1,728 | 3,354 | +94% | 0 | 0 | — |
case-21 | fail→fail | 10,433 | 9,260 | -11% | 1 | 1 | 0% | 2,230 | 4,409 | +98% | 0 | 0 | — |
case-22 | fail→fail | 13,531 | 10,496 | -22% | 1 | 1 | 0% | 2,540 | 4,524 | +78% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +18 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.