wycheproof

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Wycheproof

Wycheproof

Wycheproof is an extensive collection of test vectors designed to verify the correctness of cryptographic implementations and test against known attacks. Originally developed by Google, it is now a community-managed project where contributors can add test vectors for specific cryptographic constructions.
Wycheproof 是一个广泛的测试向量集合,旨在验证密码学实现的正确性,并针对已知攻击进行测试。它最初由 Google 开发,现在是一个社区管理的项目,贡献者可以为特定的密码学结构添加测试向量。

Background

背景

Key Concepts

核心概念

ConceptDescription
Test vectorInput/output pair for validating crypto implementation correctness
Test groupCollection of test vectors sharing attributes (key size, IV size, curve)
Result flagIndicates if test should pass (valid), fail (invalid), or is acceptable
Edge case testingTesting for known vulnerabilities and attack patterns
概念描述
测试向量用于验证密码学实现正确性的输入/输出对
测试组共享属性(密钥大小、IV大小、曲线)的测试向量集合
结果标志指示测试应通过(有效)、失败(无效)还是可接受
边缘情况测试针对已知漏洞和攻击模式进行测试

Why This Matters

重要性

Cryptographic implementations are notoriously difficult to get right. Even small bugs can:
  • Expose private keys
  • Allow signature forgery
  • Enable message decryption
  • Create consensus problems when different implementations accept/reject the same inputs
Wycheproof has found vulnerabilities in major libraries including OpenJDK's SHA1withDSA, Bouncy Castle's ECDHC, and the elliptic npm package.
密码学实现向来难以做到完全正确。即使是微小的漏洞也可能:
  • 暴露私钥
  • 允许签名伪造
  • 启用消息解密
  • 当不同实现对同一输入的接受/拒绝情况不同时,引发一致性问题
Wycheproof 已在多个主流库中发现漏洞,包括 OpenJDK 的 SHA1withDSA、Bouncy Castle 的 ECDHC 以及 elliptic npm 包。

When to Use

使用场景

Apply Wycheproof when:
  • Testing cryptographic implementations (AES-GCM, ECDSA, ECDH, RSA, etc.)
  • Validating that crypto code handles edge cases correctly
  • Verifying implementations against known attack vectors
  • Setting up CI/CD for cryptographic libraries
  • Auditing third-party crypto code for correctness
Consider alternatives when:
  • Testing for timing side-channels (use constant-time testing tools instead)
  • Finding new unknown bugs (use fuzzing instead)
  • Testing custom/experimental cryptographic algorithms (Wycheproof only covers established algorithms)
在以下场景使用 Wycheproof:
  • 测试密码学实现(AES-GCM、ECDSA、ECDH、RSA 等)
  • 验证密码代码能否正确处理边缘情况
  • 针对已知攻击向量验证实现
  • 为密码学库设置 CI/CD
  • 审计第三方密码代码的正确性
在以下场景考虑替代方案:
  • 测试计时侧信道(改用恒定时间测试工具)
  • 发现新的未知漏洞(改用模糊测试)
  • 测试自定义/实验性密码学算法(Wycheproof 仅覆盖已确立的算法)

Quick Reference

快速参考

ScenarioRecommended ApproachNotes
AES-GCM implementationUse
aes_gcm_test.json
316 test vectors across 44 test groups
ECDSA verificationUse
ecdsa_*_test.json
for specific curves
Tests signature malleability, DER encoding
ECDH key exchangeUse
ecdh_*_test.json
Tests invalid curve attacks
RSA signaturesUse
rsa_*_test.json
Tests padding oracle attacks
ChaCha20-Poly1305Use
chacha20_poly1305_test.json
Tests AEAD implementation
场景推荐方法说明
AES-GCM 实现使用
aes_gcm_test.json
44 个测试组,共 316 个测试向量
ECDSA 验证针对特定曲线使用
ecdsa_*_test.json
测试签名可塑性、DER 编码
ECDH 密钥交换使用
ecdh_*_test.json
测试无效曲线攻击
RSA 签名使用
rsa_*_test.json
测试填充 oracle 攻击
ChaCha20-Poly1305使用
chacha20_poly1305_test.json
测试 AEAD 实现

Testing Workflow

测试工作流

Phase 1: Setup                 Phase 2: Parse Test Vectors
┌─────────────────┐          ┌─────────────────┐
│ Add Wycheproof  │    →     │ Load JSON file  │
│ as submodule    │          │ Filter by params│
└─────────────────┘          └─────────────────┘
         ↓                            ↓
Phase 4: CI Integration        Phase 3: Write Harness
┌─────────────────┐          ┌─────────────────┐
│ Auto-update     │    ←     │ Test valid &    │
│ test vectors    │          │ invalid cases   │
└─────────────────┘          └─────────────────┘
Phase 1: Setup                 Phase 2: Parse Test Vectors
┌─────────────────┐          ┌─────────────────┐
│ Add Wycheproof  │    →     │ Load JSON file  │
│ as submodule    │          │ Filter by params│
└─────────────────┘          └─────────────────┘
         ↓                            ↓
Phase 4: CI Integration        Phase 3: Write Harness
┌─────────────────┐          ┌─────────────────┐
│ Auto-update     │    ←     │ Test valid &    │
│ test vectors    │          │ invalid cases   │
└─────────────────┘          └─────────────────┘

Repository Structure

仓库结构

The Wycheproof repository is organized as follows:
text
┣ 📜 README.md       : Project overview
┣ 📂 doc             : Documentation
┣ 📂 java            : Java JCE interface testing harness
┣ 📂 javascript      : JavaScript testing harness
┣ 📂 schemas         : Test vector schemas
┣ 📂 testvectors     : Test vectors
┗ 📂 testvectors_v1  : Updated test vectors (more detailed)
The essential folders are
testvectors
and
testvectors_v1
. While both contain similar files,
testvectors_v1
includes more detailed information and is recommended for new integrations.
Wycheproof 仓库的组织结构如下:
text
┣ 📜 README.md       : 项目概述
┣ 📂 doc             : 文档
┣ 📂 java            : Java JCE 接口测试工具
┣ 📂 javascript      : JavaScript 测试工具
┣ 📂 schemas         : 测试向量 schema
┣ 📂 testvectors     : 测试向量
┗ 📂 testvectors_v1  : 更新后的测试向量(更详细)
核心文件夹是
testvectors
testvectors_v1
。虽然两者包含相似的文件,但
testvectors_v1
包含更详细的信息,推荐用于新集成。

Supported Algorithms

支持的算法

Wycheproof provides test vectors for a wide range of cryptographic algorithms:
CategoryAlgorithms
Symmetric EncryptionAES-GCM, AES-EAX, ChaCha20-Poly1305
SignaturesECDSA, EdDSA, RSA-PSS, RSA-PKCS1
Key ExchangeECDH, X25519, X448
HashingHMAC, HKDF
Curvessecp256k1, secp256r1, secp384r1, secp521r1, ed25519, ed448
Wycheproof 为多种密码学算法提供测试向量:
类别算法
对称加密AES-GCM, AES-EAX, ChaCha20-Poly1305
签名ECDSA, EdDSA, RSA-PSS, RSA-PKCS1
密钥交换ECDH, X25519, X448
哈希HMAC, HKDF
曲线secp256k1, secp256r1, secp384r1, secp521r1, ed25519, ed448

Test File Structure

测试文件结构

Each JSON test file tests a specific cryptographic construction. All test files share common attributes:
json
"algorithm"         : The name of the algorithm tested
"schema"            : The JSON schema (found in schemas folder)
"generatorVersion"  : The version number
"numberOfTests"     : The total number of test vectors in this file
"header"            : Detailed description of test vectors
"notes"             : In-depth explanation of flags in test vectors
"testGroups"        : Array of one or multiple test groups
每个 JSON 测试文件针对特定的密码学结构。所有测试文件共享以下通用属性:
json
"algorithm"         : 测试的算法名称
"schema"            : JSON schema(位于 schemas 文件夹)
"generatorVersion"  : 版本号
"numberOfTests"     : 此文件中的测试向量总数
"header"            : 测试向量的详细描述
"notes"             : 测试向量中标志的深入解释
"testGroups"        : 一个或多个测试组的数组

Test Groups

测试组

Test groups group sets of tests based on shared attributes such as:
  • Key sizes
  • IV sizes
  • Public keys
  • Curves
This classification allows extracting tests that meet specific criteria relevant to the construction being tested.
测试组基于共享属性对测试进行分组,例如:
  • 密钥大小
  • IV 大小
  • 公钥
  • 曲线
这种分类允许提取与正在测试的结构相关的特定测试用例。

Test Vector Attributes

测试向量属性

Shared Attributes

共享属性

All test vectors contain four common fields:
  • tcId: Unique identifier for the test vector within a file
  • comment: Additional information about the test case
  • flags: Descriptions of specific test case types and potential dangers (referenced in
    notes
    field)
  • result: Expected outcome of the test
The
result
field can take three values:
ResultMeaning
validTest case should succeed
acceptableTest case is allowed to succeed but contains non-ideal attributes
invalidTest case should fail
所有测试向量包含四个通用字段:
  • tcId: 文件内测试向量的唯一标识符
  • comment: 测试用例的附加信息
  • flags: 特定测试用例类型和潜在风险的描述(参考
    notes
    字段)
  • result: 测试的预期结果
result
字段可以取三个值:
结果含义
valid测试用例应通过
acceptable测试用例可通过,但包含非理想属性
invalid测试用例应失败

Unique Attributes

独有属性

Unique attributes are specific to the algorithm being tested:
AlgorithmUnique Attributes
AES-GCM
key
,
iv
,
aad
,
msg
,
ct
,
tag
ECDH secp256k1
public
,
private
,
shared
ECDSA
msg
,
sig
,
result
EdDSA
msg
,
sig
,
pk
独有属性特定于所测试的算法:
算法独有属性
AES-GCM
key
,
iv
,
aad
,
msg
,
ct
,
tag
ECDH secp256k1
public
,
private
,
shared
ECDSA
msg
,
sig
,
result
EdDSA
msg
,
sig
,
pk

Implementation Guide

实现指南

Phase 1: Add Wycheproof to Your Project

阶段 1:将 Wycheproof 添加到项目中

Option 1: Git Submodule (Recommended)
Adding Wycheproof as a git submodule ensures automatic updates:
bash
git submodule add https://github.com/C2SP/wycheproof.git
Option 2: Fetch Specific Test Vectors
If submodules aren't possible, fetch specific JSON files:
bash
#!/bin/bash

TMP_WYCHEPROOF_FOLDER=".wycheproof/"
TEST_VECTORS=('aes_gcm_test.json' 'aes_eax_test.json')
BASE_URL="https://raw.githubusercontent.com/C2SP/wycheproof/master/testvectors_v1/"
选项 1:Git 子模块(推荐)
将 Wycheproof 添加为 Git 子模块可确保自动更新:
bash
git submodule add https://github.com/C2SP/wycheproof.git
选项 2:获取特定测试向量
如果无法使用子模块,可以获取特定的 JSON 文件:
bash
#!/bin/bash

TMP_WYCHEPROOF_FOLDER=".wycheproof/"
TEST_VECTORS=('aes_gcm_test.json' 'aes_eax_test.json')
BASE_URL="https://raw.githubusercontent.com/C2SP/wycheproof/master/testvectors_v1/"

Create wycheproof folder

Create wycheproof folder

mkdir -p $TMP_WYCHEPROOF_FOLDER
mkdir -p $TMP_WYCHEPROOF_FOLDER

Request all test vector files if they don't exist

Request all test vector files if they don't exist

for i in "${TEST_VECTORS[@]}"; do if [ ! -f "${TMP_WYCHEPROOF_FOLDER}${i}" ]; then curl -o "${TMP_WYCHEPROOF_FOLDER}${i}" "${BASE_URL}${i}" if [ $? -ne 0 ]; then echo "Failed to download ${i}" exit 1 fi fi done
undefined
for i in "${TEST_VECTORS[@]}"; do if [ ! -f "${TMP_WYCHEPROOF_FOLDER}${i}" ]; then curl -o "${TMP_WYCHEPROOF_FOLDER}${i}" "${BASE_URL}${i}" if [ $? -ne 0 ]; then echo "Failed to download ${i}" exit 1 fi fi done
undefined

Phase 2: Parse Test Vectors

阶段 2:解析测试向量

Identify the test file for your algorithm and parse the JSON:
Python Example:
python
import json

def load_wycheproof_test_vectors(path: str):
    testVectors = []
    try:
        with open(path, "r") as f:
            wycheproof_json = json.loads(f.read())
    except FileNotFoundError:
        print(f"No Wycheproof file found at: {path}")
        return testVectors

    # Attributes that need hex-to-bytes conversion
    convert_attr = {"key", "aad", "iv", "msg", "ct", "tag"}

    for testGroup in wycheproof_json["testGroups"]:
        # Filter test groups based on implementation constraints
        if testGroup["ivSize"] < 64 or testGroup["ivSize"] > 1024:
            continue

        for tv in testGroup["tests"]:
            # Convert hex strings to bytes
            for attr in convert_attr:
                if attr in tv:
                    tv[attr] = bytes.fromhex(tv[attr])
            testVectors.append(tv)

    return testVectors
JavaScript Example:
javascript
const fs = require('fs').promises;

async function loadWycheproofTestVectors(path) {
  const tests = [];

  try {
    const fileContent = await fs.readFile(path);
    const data = JSON.parse(fileContent.toString());

    data.testGroups.forEach(testGroup => {
      testGroup.tests.forEach(test => {
        // Add shared test group properties to each test
        test['pk'] = testGroup.publicKey.pk;
        tests.push(test);
      });
    });
  } catch (err) {
    console.error('Error reading or parsing file:', err);
    throw err;
  }

  return tests;
}
确定算法对应的测试文件并解析 JSON:
Python 示例:
python
import json

def load_wycheproof_test_vectors(path: str):
    testVectors = []
    try:
        with open(path, "r") as f:
            wycheproof_json = json.loads(f.read())
    except FileNotFoundError:
        print(f"No Wycheproof file found at: {path}")
        return testVectors

    # Attributes that need hex-to-bytes conversion
    convert_attr = {"key", "aad", "iv", "msg", "ct", "tag"}

    for testGroup in wycheproof_json["testGroups"]:
        # Filter test groups based on implementation constraints
        if testGroup["ivSize"] < 64 or testGroup["ivSize"] > 1024:
            continue

        for tv in testGroup["tests"]:
            # Convert hex strings to bytes
            for attr in convert_attr:
                if attr in tv:
                    tv[attr] = bytes.fromhex(tv[attr])
            testVectors.append(tv)

    return testVectors
JavaScript 示例:
javascript
const fs = require('fs').promises;

async function loadWycheproofTestVectors(path) {
  const tests = [];

  try {
    const fileContent = await fs.readFile(path);
    const data = JSON.parse(fileContent.toString());

    data.testGroups.forEach(testGroup => {
      testGroup.tests.forEach(test => {
        // Add shared test group properties to each test
        test['pk'] = testGroup.publicKey.pk;
        tests.push(test);
      });
    });
  } catch (err) {
    console.error('Error reading or parsing file:', err);
    throw err;
  }

  return tests;
}

Phase 3: Write Testing Harness

阶段 3:编写测试工具

Create test functions that handle both valid and invalid test cases.
Python/pytest Example:
python
import pytest
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

tvs = load_wycheproof_test_vectors("wycheproof/testvectors_v1/aes_gcm_test.json")

@pytest.mark.parametrize("tv", tvs, ids=[str(tv['tcId']) for tv in tvs])
def test_encryption(tv):
    try:
        aesgcm = AESGCM(tv['key'])
        ct = aesgcm.encrypt(tv['iv'], tv['msg'], tv['aad'])
    except ValueError as e:
        # Implementation raised error - verify test was expected to fail
        assert tv['result'] != 'valid', tv['comment']
        return

    if tv['result'] == 'valid':
        assert ct[:-16] == tv['ct'], f"Ciphertext mismatch: {tv['comment']}"
        assert ct[-16:] == tv['tag'], f"Tag mismatch: {tv['comment']}"
    elif tv['result'] == 'invalid' or tv['result'] == 'acceptable':
        assert ct[:-16] != tv['ct'] or ct[-16:] != tv['tag']

@pytest.mark.parametrize("tv", tvs, ids=[str(tv['tcId']) for tv in tvs])
def test_decryption(tv):
    try:
        aesgcm = AESGCM(tv['key'])
        decrypted_msg = aesgcm.decrypt(tv['iv'], tv['ct'] + tv['tag'], tv['aad'])
    except ValueError:
        assert tv['result'] != 'valid', tv['comment']
        return
    except InvalidTag:
        assert tv['result'] != 'valid', tv['comment']
        assert 'ModifiedTag' in tv['flags'], f"Expected 'ModifiedTag' flag: {tv['comment']}"
        return

    assert tv['result'] == 'valid', f"No invalid test case should pass: {tv['comment']}"
    assert decrypted_msg == tv['msg'], f"Decryption mismatch: {tv['comment']}"
JavaScript/Mocha Example:
javascript
const assert = require('assert');

function testFactory(tcId, tests) {
  it(`[${tcId + 1}] ${tests[tcId].comment}`, function () {
    const test = tests[tcId];
    const ed25519 = new eddsa('ed25519');
    const key = ed25519.keyFromPublic(toArray(test.pk, 'hex'));

    let sig;
    if (test.result === 'valid') {
      sig = key.verify(test.msg, test.sig);
      assert.equal(sig, true, `[${test.tcId}] ${test.comment}`);
    } else if (test.result === 'invalid') {
      try {
        sig = key.verify(test.msg, test.sig);
      } catch (err) {
        // Point could not be decoded
        sig = false;
      }
      assert.equal(sig, false, `[${test.tcId}] ${test.comment}`);
    }
  });
}

// Generate tests for all test vectors
for (var tcId = 0; tcId < tests.length; tcId++) {
  testFactory(tcId, tests);
}
创建处理有效和无效测试用例的测试函数。
Python/pytest 示例:
python
import pytest
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

tvs = load_wycheproof_test_vectors("wycheproof/testvectors_v1/aes_gcm_test.json")

@pytest.mark.parametrize("tv", tvs, ids=[str(tv['tcId']) for tv in tvs])
def test_encryption(tv):
    try:
        aesgcm = AESGCM(tv['key'])
        ct = aesgcm.encrypt(tv['iv'], tv['msg'], tv['aad'])
    except ValueError as e:
        # Implementation raised error - verify test was expected to fail
        assert tv['result'] != 'valid', tv['comment']
        return

    if tv['result'] == 'valid':
        assert ct[:-16] == tv['ct'], f"Ciphertext mismatch: {tv['comment']}"
        assert ct[-16:] == tv['tag'], f"Tag mismatch: {tv['comment']}"
    elif tv['result'] == 'invalid' or tv['result'] == 'acceptable':
        assert ct[:-16] != tv['ct'] or ct[-16:] != tv['tag']

@pytest.mark.parametrize("tv", tvs, ids=[str(tv['tcId']) for tv in tvs])
def test_decryption(tv):
    try:
        aesgcm = AESGCM(tv['key'])
        decrypted_msg = aesgcm.decrypt(tv['iv'], tv['ct'] + tv['tag'], tv['aad'])
    except ValueError:
        assert tv['result'] != 'valid', tv['comment']
        return
    except InvalidTag:
        assert tv['result'] != 'valid', tv['comment']
        assert 'ModifiedTag' in tv['flags'], f"Expected 'ModifiedTag' flag: {tv['comment']}"
        return

    assert tv['result'] == 'valid', f"No invalid test case should pass: {tv['comment']}"
    assert decrypted_msg == tv['msg'], f"Decryption mismatch: {tv['comment']}"
JavaScript/Mocha 示例:
javascript
const assert = require('assert');

function testFactory(tcId, tests) {
  it(`[${tcId + 1}] ${tests[tcId].comment}`, function () {
    const test = tests[tcId];
    const ed25519 = new eddsa('ed25519');
    const key = ed25519.keyFromPublic(toArray(test.pk, 'hex'));

    let sig;
    if (test.result === 'valid') {
      sig = key.verify(test.msg, test.sig);
      assert.equal(sig, true, `[${test.tcId}] ${test.comment}`);
    } else if (test.result === 'invalid') {
      try {
        sig = key.verify(test.msg, test.sig);
      } catch (err) {
        // Point could not be decoded
        sig = false;
      }
      assert.equal(sig, false, `[${test.tcId}] ${test.comment}`);
    }
  });
}

// Generate tests for all test vectors
for (var tcId = 0; tcId < tests.length; tcId++) {
  testFactory(tcId, tests);
}

Phase 4: CI Integration

阶段 4:CI 集成

Ensure test vectors stay up to date by:
  1. Using git submodules: Update submodule in CI before running tests
  2. Fetching latest vectors: Run fetch script before test execution
  3. Scheduled updates: Set up weekly/monthly updates to catch new test vectors
通过以下方式确保测试向量保持最新:
  1. 使用 Git 子模块:在运行测试前在 CI 中更新子模块
  2. 获取最新向量:在测试执行前运行获取脚本
  3. 定期更新:设置每周/每月更新以获取新的测试向量

Common Vulnerabilities Detected

常见检测到的漏洞

Wycheproof test vectors are designed to catch specific vulnerability patterns:
VulnerabilityDescriptionAffected AlgorithmsExample CVE
Signature malleabilityMultiple valid signatures for same messageECDSA, EdDSACVE-2024-42459
Invalid DER encodingAccepting non-canonical DER signaturesECDSACVE-2024-42460, CVE-2024-42461
Invalid curve attacksECDH with invalid curve pointsECDHCommon in many libraries
Padding oracleTiming leaks in padding validationRSA-PKCS1Historical OpenSSL issues
Tag forgeryAccepting modified authentication tagsAES-GCM, ChaCha20-Poly1305Various implementations
Wycheproof 测试向量旨在检测特定的漏洞模式:
漏洞描述受影响算法示例 CVE
签名可塑性同一消息存在多个有效签名ECDSA, EdDSACVE-2024-42459
无效 DER 编码接受非规范 DER 签名ECDSACVE-2024-42460, CVE-2024-42461
无效曲线攻击使用无效曲线点的 ECDHECDH多个库中常见
填充 Oracle填充验证中的计时泄露RSA-PKCS1历史 OpenSSL 问题
标签伪造接受修改后的认证标签AES-GCM, ChaCha20-Poly1305多种实现

Signature Malleability: Deep Dive

签名可塑性:深入分析

Problem: Implementations that don't validate signature encoding can accept multiple valid signatures for the same message.
Example (EdDSA): Appending or removing zeros from signature:
text
Valid signature:   ...6a5c51eb6f946b30d
Invalid signature: ...6a5c51eb6f946b30d0000  (should be rejected)
How to detect:
python
undefined
问题: 未验证签名编码的实现可能接受同一消息的多个有效签名。
示例(EdDSA): 在签名后附加或移除零:
text
Valid signature:   ...6a5c51eb6f946b30d
Invalid signature: ...6a5c51eb6f946b30d0000  (应被拒绝)
检测方法:
python
undefined

Add signature length check

添加签名长度检查

if len(sig) != 128: # EdDSA signatures must be exactly 64 bytes (128 hex chars) return False

**Impact:** Can lead to consensus problems when different implementations accept/reject the same signatures.

**Related Wycheproof tests:**
- EdDSA: tcId 37 - "removing 0 byte from signature"
- ECDSA: tcId 06 - "Legacy: ASN encoding of r misses leading 0"
if len(sig) != 128: # EdDSA 签名必须恰好为 64 字节(128 个十六进制字符) return False

**影响:** 当不同实现对同一签名的接受/拒绝情况不同时,会引发一致性问题。

**相关 Wycheproof 测试:**
- EdDSA: tcId 37 - "removing 0 byte from signature"
- ECDSA: tcId 06 - "Legacy: ASN encoding of r misses leading 0"

Case Study: Elliptic npm Package

案例研究:elliptic npm 包

This case study demonstrates how Wycheproof found three CVEs in the popular elliptic npm package (3000+ dependents, millions of weekly downloads).
本案例研究展示了 Wycheproof 如何在流行的 elliptic npm 包(3000+ 依赖项,数百万周下载量)中发现三个 CVE。

Overview

概述

The elliptic library is an elliptic-curve cryptography library written in JavaScript, supporting ECDH, ECDSA, and EdDSA. Using Wycheproof test vectors on version 6.5.6 revealed multiple vulnerabilities:
  • CVE-2024-42459: EdDSA signature malleability (appending/removing zeros)
  • CVE-2024-42460: ECDSA DER encoding - invalid bit placement
  • CVE-2024-42461: ECDSA DER encoding - leading zero in length field
elliptic 库是一个用 JavaScript 编写的椭圆曲线密码学库,支持 ECDH、ECDSA 和 EdDSA。在版本 6.5.6 上使用 Wycheproof 测试向量发现了多个漏洞:
  • CVE-2024-42459: EdDSA 签名可塑性(附加/移除零)
  • CVE-2024-42460: ECDSA DER 编码 - 无效位放置
  • CVE-2024-42461: ECDSA DER 编码 - 长度字段前导零

Methodology

方法

  1. Identify supported curves: ed25519 for EdDSA
  2. Find test vectors:
    testvectors_v1/ed25519_test.json
  3. Parse test vectors: Load JSON and extract tests
  4. Write test harness: Create parameterized tests
  5. Run tests: Identify failures
  6. Analyze root causes: Examine implementation code
  7. Propose fixes: Add validation checks
  1. 确定支持的曲线:EdDSA 使用 ed25519
  2. 查找测试向量
    testvectors_v1/ed25519_test.json
  3. 解析测试向量:加载 JSON 并提取测试用例
  4. 编写测试工具:创建参数化测试
  5. 运行测试:识别失败用例
  6. 分析根本原因:检查实现代码
  7. 提出修复方案:添加验证检查

Key Findings

关键发现

EdDSA Issue (CVE-2024-42459):
  • Missing signature length validation
  • Allowed trailing zeros in signatures
  • Fix: Add
    if(sig.length !== 128) return false;
ECDSA Issue 1 (CVE-2024-42460):
  • Missing check for first bit being zero in DER-encoded r and s values
  • Fix: Add
    if ((data[p.place] & 128) !== 0) return false;
ECDSA Issue 2 (CVE-2024-42461):
  • DER length field accepted leading zeros
  • Fix: Add
    if(buf[p.place] === 0x00) return false;
EdDSA 问题(CVE-2024-42459):
  • 缺少签名长度验证
  • 允许签名末尾有尾随零
  • 修复:添加
    if(sig.length !== 128) return false;
ECDSA 问题 1(CVE-2024-42460):
  • 缺少对 DER 编码的 r 和 s 值首位为零的检查
  • 修复:添加
    if ((data[p.place] & 128) !== 0) return false;
ECDSA 问题 2(CVE-2024-42461):
  • DER 长度字段接受前导零
  • 修复:添加
    if(buf[p.place] === 0x00) return false;

Impact

影响

All three vulnerabilities allowed multiple valid signatures for a single message, leading to consensus problems across implementations.
Lessons learned:
  • Wycheproof catches subtle encoding bugs
  • Reusable test harnesses pay dividends
  • Test vector comments and flags help diagnose issues
  • Even popular libraries benefit from systematic test vector validation
这三个漏洞都允许同一消息存在多个有效签名,导致不同实现之间的一致性问题。
经验教训:
  • Wycheproof 能捕获细微的编码漏洞
  • 可重用的测试工具会带来长期收益
  • 测试向量的注释和标志有助于诊断问题
  • 即使是流行库也能从系统的测试向量验证中受益

Advanced Usage

高级用法

Tips and Tricks

技巧和窍门

TipWhy It Helps
Filter test groups by parametersFocus on test vectors relevant to your implementation constraints
Use test vector flagsUnderstand specific vulnerability patterns being tested
Check the
notes
field
Get detailed explanations of flag meanings
Test both encrypt/decrypt and sign/verifyEnsure bidirectional correctness
Run tests in CICatch regressions and benefit from new test vectors
Use parameterized testsGet clear failure messages with tcId and comment
技巧优势
按参数过滤测试组专注于与实现约束相关的测试向量
使用测试向量标志了解正在测试的特定漏洞模式
查看
notes
字段
获取标志含义的详细解释
同时测试加密/解密和签名/验证确保双向正确性
在 CI 中运行测试捕获回归问题并受益于新测试向量
使用参数化测试获取包含 tcId 和注释的清晰失败消息

Common Mistakes

常见错误

MistakeWhy It's WrongCorrect Approach
Only testing valid casesMisses vulnerabilities where invalid inputs are acceptedTest all result types: valid, invalid, acceptable
Ignoring "acceptable" resultImplementation might have subtle bugsTreat acceptable as warnings worth investigating
Not filtering test groupsWastes time on unsupported parametersFilter by keySize, ivSize, etc. based on your implementation
Not updating test vectorsMiss new vulnerability patternsUse submodules or scheduled fetches
Testing only one directionEncrypt/sign might work but decrypt/verify failsTest both operations
错误原因正确做法
仅测试有效用例遗漏接受无效输入的漏洞测试所有结果类型:有效、无效、可接受
忽略 "acceptable" 结果实现可能存在细微漏洞将可接受结果视为值得调查的警告
不过滤测试组在不支持的参数上浪费时间根据实现过滤 keySize、ivSize 等
不更新测试向量遗漏新的漏洞模式使用子模块或定期获取
仅测试单向操作加密/签名正常但解密/验证失败测试双向操作

Related Skills

相关技能

Tool Skills

工具技能

SkillPrimary Use in Wycheproof Testing
pytestPython testing framework for parameterized tests
mochaJavaScript testing framework for test generation
constant-time-testingComplement Wycheproof with timing side-channel testing
cryptofuzzFuzz-based crypto testing to find additional bugs
技能在 Wycheproof 测试中的主要用途
pytest用于参数化测试的 Python 测试框架
mocha用于测试生成的 JavaScript 测试框架
constant-time-testing补充 Wycheproof 进行计时侧信道测试
cryptofuzz基于模糊测试的密码学测试,以发现更多漏洞

Technique Skills

技术技能

SkillWhen to Apply
coverage-analysisEnsure test vectors cover all code paths in crypto implementation
property-based-testingTest mathematical properties (e.g., encrypt/decrypt round-trip)
fuzz-harness-writingCreate harnesses for crypto parsers (complements Wycheproof)
技能应用场景
coverage-analysis确保测试向量覆盖密码学实现的所有代码路径
property-based-testing测试数学属性(如加密/解密往返)
fuzz-harness-writing为密码学解析器创建工具(补充 Wycheproof)

Related Domain Skills

相关领域技能

SkillRelationship
crypto-testingWycheproof is a key tool in comprehensive crypto testing methodology
fuzzingUse fuzzing to find bugs Wycheproof doesn't cover (new edge cases)
技能关系
crypto-testingWycheproof 是全面密码学测试方法论中的关键工具
fuzzing使用模糊测试发现 Wycheproof 未覆盖的漏洞(新边缘情况)

Skill Dependency Map

技能依赖图

                    ┌─────────────────────┐
                    │    wycheproof       │
                    │   (this skill)      │
                    └──────────┬──────────┘
           ┌───────────────────┼───────────────────┐
           │                   │                   │
           ▼                   ▼                   ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│  pytest/mocha   │ │ constant-time   │ │   cryptofuzz    │
│ (test framework)│ │   testing       │ │   (fuzzing)     │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
         │                   │                   │
         └───────────────────┼───────────────────┘
              ┌──────────────────────────┐
              │   Technique Skills       │
              │ coverage, harness, PBT   │
              └──────────────────────────┘
                    ┌─────────────────────┐
                    │    wycheproof       │
                    │   (this skill)      │
                    └──────────┬──────────┘
           ┌───────────────────┼───────────────────┐
           │                   │                   │
           ▼                   ▼                   ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│  pytest/mocha   │ │ constant-time   │ │   cryptofuzz    │
│ (test framework)│ │   testing       │ │   (fuzzing)     │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
         │                   │                   │
         └───────────────────┼───────────────────┘
              ┌──────────────────────────┐
              │   Technique Skills       │
              │ coverage, harness, PBT   │
              └──────────────────────────┘

Resources

资源

Official Repository

官方仓库

The official repository contains:
  • All test vectors in
    testvectors/
    and
    testvectors_v1/
  • JSON schemas in
    schemas/
  • Reference implementations in Java and JavaScript
  • Documentation in
    doc/
官方仓库包含:
  • testvectors/
    testvectors_v1/
    中的所有测试向量
  • schemas/
    中的 JSON schema
  • Java 和 JavaScript 参考实现
  • doc/
    中的文档

Real-World Examples

实际示例

The pycryptodome library integrates Wycheproof test vectors in their test suite, demonstrating best practices for Python crypto implementations.
pycryptodome 库在其测试套件中集成了 Wycheproof 测试向量,展示了 Python 密码学实现的最佳实践。

Community Resources

社区资源

  • C2SP Community - Cryptographic specifications and standards community maintaining Wycheproof
  • Wycheproof issues tracker - Report bugs in test vectors or suggest new constructions
  • C2SP Community - 维护 Wycheproof 的密码学规范和标准社区
  • Wycheproof 问题追踪器 - 报告测试向量中的漏洞或建议新结构

Summary

总结

Wycheproof is an essential tool for validating cryptographic implementations against known attack vectors and edge cases. By integrating Wycheproof test vectors into your testing workflow:
  1. Catch subtle encoding and validation bugs
  2. Prevent signature malleability issues
  3. Ensure consistent behavior across implementations
  4. Benefit from community-contributed test vectors
  5. Protect against known cryptographic vulnerabilities
The investment in writing a reusable testing harness pays dividends through continuous validation as new test vectors are added to the Wycheproof repository.
Wycheproof 是验证密码学实现针对已知攻击向量和边缘情况的必备工具。通过将 Wycheproof 测试向量集成到测试工作流中:
  1. 捕获细微的编码和验证漏洞
  2. 防止签名可塑性问题
  3. 确保不同实现之间的行为一致
  4. 受益于社区贡献的测试向量
  5. 防御已知的密码学漏洞
编写可重用测试工具的投入会随着 Wycheproof 仓库添加新测试向量而持续带来回报。