Competition Rules

The competition is run by the ORGANIZING COMMITTEE.

User accounts

Anyone can create an account and post one or several challenges and/or break one or more challenges on the WhibOx Contest Edition 4 website.

The account owner may remain completely anonymous when creating an account. In addition to creating a login/password, an email address must be entered (in case the ORGANIZING COMMITTEE needs to contact the owner directly). However, the email address is not verified except for basic syntax. Users may e.g. enter their primary email address or, if they are willing to remain anonymous, may use a free service such as Mailinator to create an untraceable email address.

The same person may create several accounts. User accounts are password-protected but passwords CANNOT BE CHANGED and are NOT RECOVERABLE in case of loss. It is the users' responsibility to choose a strong enough password and to keep it in a safe place. Winners will be asked to log in and reveal their real name on the competition website if they want to be publicly awarded during the prize ceremony.

The website is public in the sense that anyone can freely browse it (including downloading challenges) but logging in is required to post or break challenges.

The competition website is referred to as the SYSTEM. This is a cloud server instance with an Intel Xeon-E2136 CPU (6 cores / 12 threads @ 3.3 GHz/4.5 GHz) with 32GB of RAM.

What is a challenge?

A challenge is a C source program that contains a function with prototype

void ECDSA_256_sign(unsigned char sig[64], const unsigned char hash[32]);

It implements an ECDSA signature algorithm on the NIST P-256 curve under some private key embedded into the code. The function ECDSA_256_sign takes two arguments:

  • hash: a pointer to the 32-byte hash of the message to be signed (the hash function is excluded from the implementation),
  • sig: the address for the output 64-byte signature.

The C language is the one accepted by GCC >= 10.1 with NO additional language dialect options. The source code must be made of generic C (which in particular excludes the use of inline assembly), and it should be re-compilable and properly executable on any x86_64 CPU using any GCC compiler of version >= 10.1 with any optimization level (i.e. still provide the expected ECDSA signature algorithm in these conditions), and with position independent code related flags (-fPIC, -fPIE and -pie).

The source file is allowed to include the GMP library (version 6.3.0) through #include <gmp.h>. Besides that, no #include or extern is allowed in the source code, and more generally linking to external libraries (even the standard C libraries) is forbidden. Any attempt to maliciously attack the SYSTEM or the computer system of contestants will lead to DISQUALIFICATION. In case evidence of malicious code is found in a challenge, contestants are invited to report the issue to the ORGANIZING COMMITTEE directly ( If contestants are suspicious that some challenge program may contain malware, they may run GCC in docker or a virtual machine, exactly like the server does (using VirtualBox).

Documentation on how the server runs is found on GitHub. Contestants are invited to download and install their own instance of the server if they want to ensure that their challenge will be accepted when submitted.

IPR and copyright disclaimer: contestants may indicate (typically in a header in their source) which license applies to their challenge program, if any.

Requirements on the source and executable

  • The source code must be no bigger than 100MB.
  • The REFERENCE COMPILERS must use at most 800MB of RAM to complete compilation.
  • The compilation must not exceed 150 seconds.
  • The executable must be 50MB in size or less,
  • The executable must use 50MB of RAM or less (this includes the stack and all global variables, at the exclusion of the code itself),
  • The executable must run in 10 seconds or less per function call. This is not absolute time but CPU time, measured within a VirtualBox VM by the SYSTEM. Contestants may check that their challenges comply with this limitation by using the utility ulimit with the −t option.
  • The following character strings are forbidden in the source code:
    • "#(wsp*)include", except #include <gmp.h>
    • "extern"
    • "_FILE__"
    • "__DATE__"
    • "__TIME"
    • "__STDC_"
    • "__asm__"
    • "syscall"
    • ".init", ".fini", ".init_array", ".fini_array", ".ctors", ".dtors"
    • "(wsp)asm(nan)"
    where "(wsp)" indicates a white space, "(wsp*)" indicates zero or more white spaces, and "(nan)" indicates any non-alphanumeric character. An occurence of either of these strings will lead to a rejection of the challenge program, even if they are embedded in (arbitrarily nested) quoted strings.
  • The executable is not allowed to perform any system call beyond reading from stdin, writing to stdout, performing allocations through brk, mmap and munmap (with some restrictions, that should be enough for using the gmp API), exit(_group) and rt_sigreturn. Any forbidden system call will kill the process as SECCOMP filters are used to enforce this. You can debug your program before submitting it using whatever system calls you want, but remember to remove the forbidden ones when submitting your challenge to the SYSTEM (under Linux, you can trace the system calls of a binary with e.g. the strace utility). The SECCOMP filters setup can be found here in the main.c file, and dedicated explanations here. Please also beware that any warning: implicit declaration of function compiler warning will be caught by the SYSTEM and this will reject your program during compilation.
  • The public key of the ECDSA implementation must not be one of the ones from the previous 2021 edition accepted candidates as they are blacklisted.

The SYSTEM will reject a program that does not comply with these requirements.

Compliance with the requirements can be tested by downloading and running a local instance of the submission server found here.

Auxiliary inputs

A challenge must come with

  • the public key corresponding to the embedded private key,
  • a proof of knowledge of the private key.

The public keys of the challenges accepted in the previous 2021 edition are blacklisted in order to avoid blind resubmissions.

The public key must be pasted into the appropriate field of the submission form as the 128-digit hexadecimal string encoding the 64-byte string \( \textsf{FE2OS}(x_Q) \parallel \textsf{FE2OS}(y_Q)\), where \( \textsf{FE2OS} \) is the "Field Element to Octet String" primitive defined in Section 3.1.3 of the BSI ECC guideline, \( (x_Q,y_Q) \) is the public key (\(x\)- and \(y\)-coordinates) and \( \parallel \) is the concatenation operator.

The proof of knowledge is a Schnorr signature of the empty message under the private key, that is a pair \( (r,s) \) such that \( \mathsf{SHA256}(s\cdot G+r\cdot Q)=r \), where \( G \) is the base point and \( Q \) is the public key. The input of \( \mathsf{SHA256} \) is the padded \(x\)-coordinate (32 bytes). The format of the proof of knowledge is similar to that of the public key. Namely, it is a 64-byte hexadecimal string obtained by concatenating \(r\) and \(s\) (each of them padded to 32 bytes).

A reference implementation with corresponding public key (formatted for submission) and a script to generate the proof of knowledge from the private key are available here.

Posting a challenge

A contestant who posts a new challenge must submit the corresponding public key to the SYSTEM for the purpose of verifying the consistency of the challenge program. This is done as follows.

Challenge-key verification procedure

  1. The SYSTEM verifies that the submitted public key has not been previously submitted, and that it is not one of the previous 2021 edition accepted candidates public keys. If this is the case, the challenge is rejected.
  2. The SYSTEM verifies that the submitted public key is a valid public key by checking that the underlying elliptic point is on the curve P-256. If not, the challenge is rejected.
  3. The SYSTEM verifies the submitted proof of knowledge. If the verification fails, the challenge is rejected.
  4. The SYSTEM compiles the challenge program and checks that it complies with the above requirements. If not, the challenge is rejected.
  5. The SYSTEM generates a number of random input hashes (32-byte strings), uses the submitted implementation of ECDSA P-256 to generate the corresponding signatures, and uses the submitted public key to verify these signatures. The number of (input hash, signature) pairs is determined by the SYSTEM but is at least 100.
  6. In case of mismatch, the procedure halts, the challenge program is rejected and the mismatching (input hash, signature) pair is returned to the submitting contestant.
  7. Finally, the challenge program is validated and:
    1. given a name by the system,
    2. assigned a PERFORMANCE SCORE (see below)
    3. declared as STANDING,
    4. assigned a STRAWBERRY score (both initialized to 0).

Programmatic API access to input-output pairs

When accepted, the challenge is published on the website for anyone to download and play with. In addition, a small subset of random hash-signature pairs is kept by the SYSTEM. The number of pairs is determined by the SYSTEM but is at least 10. These pairs can be recovered as a JSON object with the following HTTP request:

GET https://{HOST}/candidate/{id}

where {id} is the integer identifier of the challenge (not its name). No authentication is required. Example output:

  "id": 3,
  "proof_of_knowledge": "DA95FB593E561E3D24BA7C6AFFE28169EF17A76BCE9442E6EE1E768E5253E2844104C6513DD37DF82E7600018ACA5BC2AF467129DEF7903EDA693C0BBB76BD55",
  "public_key": "7D333C24CE6E539C66E6C7EF159CC1FA75F1B36321D4E6F4E3C0B42294D927A0C77DCFDE5782CF5B82B18C3499575D5191950F56678AE4F7B11815FA19A66807",
  "test_vectors": [
      "hash": "CA432252911CB7D6984354F2C08B94850C013C4A7584C53E044D5AA840234A82",
      "signature": "F946FA83BEBB4F1C31729175034A2971C1C8E9577DD7AB74DA476854157F459436A4C9EFE55DA6DC9E58B99777C6DD47F925C75B33A045F9F2E22DE7B26F6F24"
      "hash": "E8720F0770A55ECF716B8E7E5EDFC7DE29A0D60D34FB22D999B6652F9EFC5092",
      "signature": "EBDA369AABA4C9C1D234A089C9E8C4A5C58474B281FB03F87DDB796A8379604BAD85EFB1FFAAB2866F5F58BCA2B10F9837598C09EC46E739D78EBB5E0A0F05E7"
      "hash": "0011F7845B3B0177A8FFA0B091EF6E18CBAC48B9CB1D094AA132D115B29A3C17",
      "signature": "2DFCE93EF82D986F4D70D9A13DCAE09710251EBC410C5C9D40D2A58DB2072422AB5D507051B6E84C76D7EB0C9171663D17D0ADE206B06D5CA32C212BF7CA9202"
      "hash": "74EE4AC38DAFE9E412A6BFD4B5C700D323647DF08E5D9CA6424FB9545AF8A921",
      "signature": "4ACADB17EEA49231B8D418B4183F60108687A545C51329F8305C975CB0FA8BE745A668E46EA2667391044811C37C3B66E372DD7F85E026BCBCE5269E966153AD"
      "hash": "635E98797C020703DF02401FC7875F6A898DAF6A97B44545085CEB7121DBF87C",
      "signature": "936F5F1BB888D9767C85F35FD1E2D3B7E00B756CF1132CB3BC5D11E4F1FB9566DBB386D66EBBA03D08B8CCBCCFDCDEF9B347A3F0FA532FF863631517892631C7"
      "hash": "6A80250B5D99AB19E7A22CD0C693DB5512171BA52F4CD6E5ED57D0F235BE5744",
      "signature": "56C083E3EB85F6A7CEF35759717DC22CC3680A0347AC438462B58560D68EAA083E76468601FD86E4CB0AC3DCD72B76193193A91431ABB709F77106AB1E1004D6"
      "hash": "C27A231D7FA08308DDFD708E1164885BC69126E6DEC7362388AF6E9AB5A9011F",
      "signature": "15D5D181EE52D3946B720D4DBF6A1EF71D0A4DAB88B7D5339C1D74661029EB899624CF95A91163FCA4561091E780B7B677095EE3CF1F84FA268C6BEB299FADF4"
      "hash": "50365D99155091C54E137CC3E7FB0B706BB0EFED921F690354F4AA08D783C94C",
      "signature": "3F90C0F2912B52CEC781ADCF6E489B636549E543DBCE133D63B8B1B5E620291D5172A8A5BA844FB56E33C7D2324369DAF0BD29AC7FA0CDDD823EB9911577C71D"
      "hash": "4E9A84C83082848926BF0B89E7D3585BE767C8657B4FFBAA9370C9839EC4D26E",
      "signature": "5C6135E8BEDC689177CFE3AA25E6ED1EB8904DEB7E5967DDE901EAA3C5AE4A8D6A5C8BEB4A350E9A7828CCDC6904893CD16F2721D14320F9FE95C507F58B8B00"
      "hash": "743E576BD584EEA6EDFE32CD3ECC3BB6C013258539CC31C653C31F7371E72A90",
      "signature": "15A68010CF6EF4C2C29E9549D20532B4E86BECB18AA2C3338BCDE8081BF634F87FC5610E6978072CF8851ECBBF0377084E12B23130A8A2F84062C81B8227DFE7"

Performance scores

The performance score of a challenge is measured by the SYSTEM when validating its consistency at posting time. Challenges with a higher performance score collect STRAWBERRY points faster. The score is assigned as follows.

Execution time. The SYSTEM measures the average CPU time consumed by the challenge program and determines the fraction \[f_{\text{time}} = \frac{\text{average time}}{ 10 \text{ seconds} }\;.\]

Code size. The SYSTEM measures the size of the executable and determines the fraction \[f_{\text{size}} = \frac{\text{code size}}{ 50 \text{ MB} }\;.\]

RAM usage. The SYSTEM measures the average RAM consumption of the executable and determines the fraction \[f_{\text{memory}} = \frac{\text{average RAM}}{ 50 \text{ MB} }\;.\]

The performance score of the challenge is evaluated as \[\mathtt{perf\_score} = \log_2 \left(\frac{2}{f_{\text{time}} \cdot f_{\text{size}} \cdot f_{\text{memory}}}\right)\;.\]

Note that the performance score of a challenge that meets the allowed maximal limits is equal to \(1\). Challenges that are either smaller, faster or less memory-consuming get a higher perfomance score.

Winning strawberries

A contestant may post challenges anytime between the STARTING DATE and the POSTING DEADLINE.

A challenge gets more and more STRAWBERRIES as time goes by, as long as it is not BROKEN. In this fourth edition of the competition, time has a granularity of 1 minute instead of 1 day.

At the time \(t_{post}\) the challenge is posted, its STRAWBERRY score is set to \(0\). The STRAWBERRY score then increases quadratically with time as \[\mathtt{strawberries} = \mathtt{perf\_score} \times \left(\frac{t-t_{post}}{24\cdot 60}\right)^2\] where \(t-t_{post}\) is the number of minutes elapsed since the challenge was posted and \(\mathit{perf\_score}\in[1,+\infty)\) is its performance score (see above).

If the challenge is BROKEN for the first time at time \(t_{break}\), its STRAWBERRY score becomes \[\mathtt{strawberries} = \mathtt{perf\_score} \times \left(\frac{t_{break}-t_{post}-\left(t - t_{break}\right)}{24\cdot 60}\right)^2 \;,\] meaning that its progression is reversed symmetrically until it reaches \(0\). It then sticks to it.

When the FINAL DEADLINE is reached, the STRAWBERRY scores of all challenges freeze.

Breaking challenges

A contestant may BREAK any challenge by submitting a candidate key to the SYSTEM. The challenge may be STANDING, or already BROKEN.

Key verification procedure: Given the submitted key, the SYSTEM

  1. generates the public key corresponding to the submitted private key,
  2. fetches the public key of the target challenge,
  3. 3. verifies that the two public keys match.
The submitted private key is erased as soon as the verification is completed.

In case of mismatch, the break is rejected. Otherwise, the submitting contestant is notified that the break is accepted. If the challenge was STANDING, it is declared as BROKEN at the time the SYSTEM accepted the break.

Contestants may BREAK challenges until the FINAL DEADLINE.

Winning bananas

Every newly registered user, referred to as a contestant, is assigned a BANANA score initialized to 0.

A contestant whose BREAK has been accepted by the SYSTEM gets a chance to increase their BANANA score. Noting \(\mathtt{strawberries}\) the current STRAWBERRY score of the challenge and \(\mathtt{bananas}\) the contestant's current BANANA score, \(\mathtt{bananas}\) is updated as \[\mathtt{bananas} = \max(\mathtt{bananas}, \mathtt{strawberries})\;.\]

Winning the competition

The winners are determined at the time of the FINAL DEADLINE. There are 2 winners, the STRAWBERRY WINNER and the BANANA WINNER.

The strawberry winner

The WINNING CHALLENGE is the challenge (STANDING or BROKEN) which, by STRAWBERRY score, has reached the highest peak between the STARTING DATE and the FINAL DEADLINE.

The STRAWBERRY WINNER is the contestant who posted the WINNING CHALLENGE.

The banana winner

The BANANA WINNER is the contestant with the highest BANANA score at the time of the FINAL DEADLINE.

Cash prizes

A 2000$ cash prize will be shared between the winners, as follows:

  • Designers' podium:
    • TBA for the strawberry winner
    • TBA for the second highest strawberry score
    • TBA for the third highest strawberry score
  • Attackers' podium:
    • TBA for the banana winner
    • TBA for the second highest banana score
    • TBA for the third highest banana score


At any time, the ORGANIZING COMMITTEE may DISQUALIFY a contestant in case of misconduct during the competition. Examples of misconduct include

  • posting a challenge program that does not produce a verifiable ECDSA signature on P-256 curve with probablity 1,
  • posting a challenge program that contains malware,
  • attempting to attack/hack the SYSTEM or the computer system of contestants in any manner.

The user account of a DISQUALIFIED contestant is disabled and challenges that the contestant has posted may be withdrawn from the competition on a case-by-case basis.

Terms of reference

Important dates
STARTING DATEMay 26, 2024 @ 23:59 AoE (May 27, 2024 @ 11:59 UTC)
POSTING DEADLINEAugust 08, 2024 @ 23:59 AoE (August 09, 2024 @ 11:59 UTC)
FINAL DEADLINESeptember 01, 2024 @ 23:59 AoE (September 02, 2024 @ 11:59 UTC, few days before CHES 2024)
System and challenges
SYSTEMServer comprising the competition website and tools for compiling and testing challenge programs. The compilation environment is fully described in this dockerfile.
REFERENCE COMPILER gcc version 13.2.1
REFERENCE IMPLEMENTATIONdECDSA.c file available from this GitHub repository.
BROKEN (challenge) At least one contestant has been able to provide the SYSTEM with the private ECDSA key that passes the key verification procedure.
STANDING (challenge) A challenge that is not BROKEN.
Winning contestants
WINNING CHALLENGE Challenge which STRAWBERRY score has reached the highest peak between the STARTING DATE and the FINAL DEADLINE.
BANANA WINNER Contestant with the highest BANANA score at the time of the FINAL DEADLINE.
DISQUALIFIED (contestant) Misconducting contestant excluded from the competition and whose challenges may be withdrawn.
Organizing committee
Twitter@WhiboxC (WhibOx Contest Organizing Committee)