Generare codici con Arduino e resistori

Avrei una curiosità: secondo voi, è possibile generare codici univoci utilizzando solo dei resistori di valore diverso e solo uno o due pin di Aruino, digitali o analogici?

Mi servirebbe riuscire a generare, tramite un sistema di resistori, un numero elevato di codici diversi, almeno un 100.000 o più e leggerli con Arduino semplicemente trami uno o, al massimo, due dei suoi pin in input (che siano analogici o digitali non è importante).

Stavo pensando, ad esempio, di utilizzare dei partitori, ma poi quanti codici riuscirei a generare? Magari potrei usare due ingressi analogici e accoppiare il valore di un partitore con l'altro per generare il codice, ma non riesco ad immaginare quante combinazioni riuscirei ad avere.
Su ognuno dei due canali riuscirei a leggere 1024 livelli di valore diversi.. quanti codici univoci interpretabili da Arduino riuscirei a generare?

Mi date qualche consiglio, per favore?

Ci sarebbe la funzione random dell IDE di Arduino

Mah ... io, dovendole fare, farei le cose fatte bene ... https://www.sparkfun.com/products/11551 (... "Each ATSHA204 ships with a guaranteed unique 72-bit serial number"), costa poco e usa un solo pin digitale :wink:

Guglielmo

Da un punto di vista puramente teorico ottieni 1024*1024 possibili combinazione, ovvero 1048576 diversi valori, dal punto di vista pratico sono molto di meno, prima di tutto devi fare i conti con il naturale errore di +/- 1 count che hanno tutti gli ADC, ovvero la lettura fluttua sempre un count sopra e uno sotto al valore reale, già questa cosa ti riduce ad 1/3 le possibili combinazioni discriminabili, però il vero fattore limitante è la precisione delle resistenze e negli step disponibili con le serie.
In pratica anche ammesso che usi resistenze al 1% al massimo ottieni 500-600 diverse combinazioni usando due distinti ingressi analogici.

gpb01:
Mah ... io, dovendole fare, farei le cose fatte bene ... https://www.sparkfun.com/products/11551 (... "Each ATSHA204 ships with a guaranteed unique 72-bit serial number"), costa poco e usa un solo pin digitale :wink:

Oppure gli iButton di Maxim.

@astrobeed: era quello che temevo, in effetti, i valori sono troppo affetti da errore :frowning:

@gpb01: è un'ottima alternativa, ma non capisco come funziona, cioè, non capisco se il chip ha già un numero univoco o se gli deve essere impartito prima via software.
Non capisco nemmeno se per leggerlo da Arduino c'è bisogno di avere delle informazioni sul chip o se con lo stesso codice su Arduino è possibile leggere più di un chip ATSHA204 senza distinzioni.

Ogni ic arriva con un codice unico a 72 bit (4.72 * 10^21 diverse combinazioni), in più hai 4.5k di EEPROM in cui memorizzare ulteriori informazioni a tuo piacere.
Con lo stesso codice per Arduino, vedi libreria linkata da Sparkfun, leggi tutte le key che ti pare.

Questo PRNG usa un po' più componenti di quelli da te specificati:
http://robseward.com/misc/RNG2/

Credo che funzioni col protocollo simile al 1-wire, supportato dalla sua libreria che tra le funzioni ha anche la generazione di numeri casuali

The ATSHA204 can generate high-quality random numbers and employ them for any purpose, including usage as part of the crypto protocols of this chip.

astrobeed:

[quote author=marcus barnet link=topic=157878.msg1182413#msg1182413 date=1364898878]
@gpb01: è un'ottima alternativa, ma non capisco come funziona, cioè, non capisco se il chip ha già un numero univoco o se gli deve essere impartito prima via software.
Non capisco nemmeno se per leggerlo da Arduino c'è bisogno di avere delle informazioni sul chip o se con lo stesso codice su Arduino è possibile leggere più di un chip ATSHA204 senza distinzioni.

Ogni ic arriva con un codice unico a 72 bit (4.72 * 10^21 diverse combinazioni), in più hai 4.5k di EEPROM in cui memorizzare ulteriori informazioni a tuo piacere.
Con lo stesso codice per Arduino, vedi libreria linkata da Sparkfun, leggi tutte le key che ti pare.

[/quote]
Si, la stavo leggendo solo che non capisco a cosa serve il MAC Challenge perchè avevo capito che il numero univoco fosse il numero seriale.

Cioè, pensavo che potevo accedere al valore del numero univoco contenuto nel chip già solo con la funzione serialNumberExample().

E' corretto o sto facendo degli errori nella comprensione del codice?
A cosa serve il Mac Challenge?

const int sha204Pin = 7;

atsha204Class sha204(sha204Pin);

void setup()
{
  Serial.begin(9600);
  Serial.println("Sending a Wakup Command. Response should be:\r\n4 11 33 43:");
  Serial.println("Response is:");
  wakeupExample();
  Serial.println();
  Serial.println("Asking the SHA204's serial number. Response should be:");
  Serial.println("1 23 x x x x x x x EE");
  Serial.println("Response is:");
  serialNumberExample();
  Serial.println();
  Serial.println("Sending a MAC Challenge. Response should be:");
  Serial.println("23 6 67 0 4F 28 4D 6E 98 62 4 F4 60 A3 E8 75 8A 59 85 A6 79 96 C4 8A 88 46 43 4E B3 DB 58 A4 FB E5 73");
  Serial.println("Response is:");
  macChallengeExample();
}

void loop()
{
}

byte wakeupExample()
{
  uint8_t response[SHA204_RSP_SIZE_MIN];
  byte returnValue;
  
  returnValue = sha204.sha204c_wakeup(&response[0]);
  for (int i=0; i<SHA204_RSP_SIZE_MIN; i++)
  {
    Serial.print(response[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
  
  return returnValue;
}

byte serialNumberExample()
{
  uint8_t serialNumber[9];
  byte returnValue;
  
  returnValue = sha204.getSerialNumber(serialNumber);
  for (int i=0; i<9; i++)
  {
    Serial.print(serialNumber[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
  
  return returnValue;
}

byte macChallengeExample()
{
  uint8_t command[MAC_COUNT_LONG];
  uint8_t response[MAC_RSP_SIZE];

  const uint8_t challenge[MAC_CHALLENGE_SIZE] = {
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
  };

  uint8_t ret_code = sha204.sha204m_execute(SHA204_MAC, 0, 0, MAC_CHALLENGE_SIZE,
    (uint8_t *) challenge, 0, NULL, 0, NULL, sizeof(command), &command[0],
    sizeof(response), &response[0]);

  for (int i=0; i<SHA204_RSP_SIZE_MAX; i++)
  {
    Serial.print(response[i], HEX);
    Serial.print(' ');
  }
  Serial.println();
  
  return ret_code;
}

In crittografia, un MAC è un codice di autenticazione di un messaggio:

Una specie di firma digitale.

leo72:
Questo PRNG usa un po' più componenti di quelli da te specificati:
RNG Version 2

Ma a me non serve generare numeri casuali con Arduino, se ho ben capito cosa fa il circuito del link che mi hai postato.

A me serve avere un numero elevato di circuiti separati da Arduino, ognuno con un codice univoco ben preciso, in modo da poter riconoscere ogni circuito una volta che io lo collego al mio Arduino.

leo72:
In crittografia, un MAC è un codice di autenticazione di un messaggio:
Message authentication code - Wikipedia
Una specie di firma digitale.

Ti ringrazio Leo!

Quindi a me serve solo la funzione per la lettura del numero seriale che dovrebbe essere il numero che è già impostato nel chip e che è univoco, cioè, non ci saranno altri chip atsha204 con lo stesso codice, giusto?

Perchè dato che il MAC richiede uno scambio di dati, non posso prenderlo in considerazione dato che non devo interagire con un solo chip. Corretto?

Questo è quello che hai scritto inizialmente :P:

Boh, questo lo sai tu. Io non ho capito cosa vuoi fare. :sweat_smile:

leo72:

[quote author=marcus barnet link=topic=157878.msg1182435#msg1182435 date=1364899906]

leo72:
Questo PRNG usa un po' più componenti di quelli da te specificati:
RNG Version 2

Ma a me non serve generare numeri casuali con Arduino, se ho ben capito cosa fa il circuito del link che mi hai postato.

Questo è quello che hai scritto inizialmente :P:

[/quote]

Secondo me, non ho spiegato bene quello che volevo fare all'inizio.
Cioè, non volevo intendere che volevo generare quei codici con Arduino, ma generarli con un circuito e leggerli da Arduino :slight_smile: Mi scuso per la confusione che ho fatto. :blush:

Mi spiego meglio: ho un Arduino UNO e poi dei circuiti a parte, magari inseriti in una black box, che poi collego ad Arduino.
I circuiti all'interno della black box devono essere in grado di comunicare un codice ad Arduino quando io li collego a quest'ultimo.
Il codice deve essere univoco in modo che io possa distinguere i vari circuiti che collego.
Il codice, quindi, mi viene dato dal circuito e non è generato da Arduino.
Inizialmente, avevo pensato di realizzare questi circuiti con dei resistori in modo da ottenere dei valori numeri diversi quando andavo a collegarli ad Arduino.
Poi, ho pensato che questi circuiti possono, in realtà, essere costituiti dal chip atsha204, come mi ha suggerito Guglielmo anche perchè la cosa sarebbe poco costosa; il tutto sarebbe accettabile se, come ho capito, per leggere il codice contenuto in ogni chip, mi basta usare la funzione generica per la lettura del codice seriale.
Per il MAC mi pare di capire che occorre scambiarsi dei pacchetti e la cosa non sarebbe ottimale, tanto a me serve solo ed esclusivamente riuscire a leggere un codice univoco una volta che collego il circuito al mio Arduino.

Si, a te occorre solo la lettura del numero di serie UNIVOCO. Tutte le altre funzioni sono per altri scopi, come autenticazione di messaggi, ecc. ecc.

Ogni singolo chip ha un suo codice UNIVOCO.

Guglielmo

gpb01:

[quote author=marcus barnet link=topic=157878.msg1182437#msg1182437 date=1364900135]
...
Quindi a me serve solo la funzione per la lettura del numero seriale che dovrebbe essere il numero che è già impostato nel chip e che è univoco, cioè, non ci saranno altri chip atsha204 con lo stesso codice, giusto?
...

Si, a te occorre solo la lettura del numero di serie UNIVOCO. Tutte le altre funzioni sono per altri scopi, come autenticazione di messaggi, ecc. ecc.

Ogni singolo chip ha un suo codice UNIVOCO.

Guglielmo
[/quote]

Secondo la tua esperienza, potrei avere problemi nel leggere il codice seriale con Arduino?
Nel sito di sparkfun, nei commenti, mi sembra di aver letto che ci potrebbero essere problemi sulla velocità di comunicazione tra i due device e sulla precisione.
Oppure questo è valido solo per l'uso delle altre funzioni che, comunque, a me non servono?

Puoi facilmente risolvere, spendendo meno di 2 Euro per ogni chiave, usando un ATtiny, il più piccolo di tutti, al cui interno codifichi la chiave univoca, lunga quanto ti pare, che trasmette in continuazione, p.e. tramite seriale, non appena viene alimentato.
Il il codice sono poche righe, devi solo decidere quale interfaccia di connessione utilizzare, potrebbe andare bene la OneWire che ti impegna un solo pin di Arduino.
Il circuito della key puoi facilmente montarlo su 1000 fori in quanto devi solo collegare l'alimentazione al Tiny, mettere un condensatore da 100 nf, portare su un connettore Vdd, GND e i pin coinvolti per la trasmissione dati.

Ma li colleghi "a caldo"? Cioè con l'Arduino sotto tensione?
Quel chip che ti è stato consigliato comunica via I2C, io non ho mai fatto dei test per vedere se un dispositivo I2C si "aggancia a caldo" ad un bus I2C già in tensione.

Il codice deve essere univoco in modo che io possa distinguere i vari circuiti che collego.

Ma di quanti dispositivi periferici si parla? Se son pochi, potresti anche prevedere un piccolo Attiny25/45/85 con all'interno preregistrato il codice generato in precedenza, che fornisce solo dietro richiesta esplicita. Consiglio una MCU perché con i fuse puoi proteggere la memoria dalla lettura fatta da un malintenzionato che può volerti copiare un dispositivo. Basta quindi che l'Arduino invii la chiave di "lettura" ed il Tiny risponde con il suo codice. Se questo è giusto, il dispositivo ha accesso a qualcosa.

Per il MAC mi pare di capire che occorre scambiarsi dei pacchetti e la cosa non sarebbe ottimale, tanto a me serve solo ed esclusivamente riuscire a leggere un codice univoco una volta che collego il circuito al mio Arduino.

Il MAC prevede l'uso di una chiave privata da distribuire in precedenza sia al master che allo slave.