Frage:
Einfache Hash-Funktion zur Implementierung auf einem Mikrocontroller
alexbb
2013-09-04 20:45:43 UTC
view on stackexchange narkive permalink

Ich suche nach einer sehr einfachen Hash-Funktion, die auf einem Mikrocontroller implementiert werden kann. Der Mikrocontroller zeigt eine 4-stellige alphanumerische Sitzungs-ID auf einem Display an. Ich möchte der Hash-Funktion eine Zählung geben und eine Zahl zurückerhalten, die später in eine 4-stellige alphanumerische Zahl umgewandelt wird. Irgendwelche Vorschläge für eine leichte Hash-Funktion?

Dies ist bei Security SE möglicherweise besser geeignet. Muss es in der Zwischenzeit kryptografisch sicher sein?
Muss nicht kryptografisch sicher sein, sondern nur leicht.
Was ist der Bereich der eingegebenen "Zählwerte"? Warum nicht einfach den Eingabewert selbst verwenden ... warum sich die Mühe machen, ihn zu hashen?
Wie wäre es mit CRC16 / 32?
Der Zählwert ist eine Zahl, die ich privat halten möchte. Nichts _bad_ wird passieren, wenn es entdeckt wird, aber es ist nur aus Sicht der Benutzerfreundlichkeit, dass es nicht angezeigt wird. Über CRC, ich habe nie darüber nachgedacht, es scheint eine gute Option zu sein.
Was ist das Mikro? Einige haben ein Hardware-CRC-Peripheriegerät auf dem Chip, das so leicht wie möglich ist.
Das Mikro ist ein MSP430, aber ich habe gerade herausgefunden, dass es keine gute Idee ist, das CRC-Modul zu verwenden, da das Mikro möglicherweise gleichzeitig Nachrichten mit dem CRC-Modul verarbeitet.
@Polynomial es scheint auch hier gut zu laufen und auf eine Migration zu warten.
@Kortuk Da es keine Sicherheitsanforderungen gibt, stimme ich zu. Wäre es kryptografisch sicher sein müssen, wäre eine Migration eine gute Idee gewesen.
@Polynomial Ich musste für die Arbeit kryptografisch sicher arbeiten. Ich habe das Gefühl, dass es Überschneidungen geben könnte, aber wenn es kryptografisch sicher sein müsste und ich keine Erfahrung hätte, würde ich eine Beratung bezahlen. :) :)
@Kortuk Dann bist du ein guter Kerl. Leider versuchen viele Leute nur, "etwas zusammenzuhalten" und eine schwache Sauce zu produzieren, insbesondere in eingebetteten Systemen, in denen die ganze Sache "Niemand wird jemals die Firmware meines Mikros zurückentwickeln" ins Spiel kommt. Hält mich in einem Job, macht aber auch allen anderen viel Ärger.
Fünf antworten:
Polynomial
2013-09-04 20:51:16 UTC
view on stackexchange narkive permalink

CRC32 würde den Job erledigen, wenn Sie keine kryptografische Sicherheit benötigen. Es gibt Ihnen einen 32-Bit-Ausgabewert und erfordert nur einfache Operationen. Auch für die meisten großen Mikrofamilien gibt es viele Implementierungen. Teilen Sie es auf 4 Bytes auf und modulieren Sie ein 32-stelliges Alphabet (1-9 A-Z, wobei ein paar Zeichen wie I und J übersprungen werden), und es gibt Ihren Code.

Ich werde das unterstützen - CRC32 ist eine gute Wahl. Es verfügt über hervorragende Nichtkollisionseigenschaften und Sie können den Speicher für eine 256-Byte-LUT sparen, wenn dies in mehreren Schichten implementiert werden kann, sowie für XOR und eine Tabellensuche für jedes Eingabebyte.
Die Fehlererkennungseigenschaften von CRC treten nur dann ein, wenn der Hamming-Abstand niedrig genug ist.Es ist also nicht optimal für allgemeines Hashing (es gibt schnellere Alternativen mit besserer Pseudozufälligkeit).Wenn die Nachrichten von OP jedoch klein genug sind, ist CRC-16 möglicherweise ideal für seine verspielte 4-stellige Anzeige.
supercat
2013-09-04 21:21:22 UTC
view on stackexchange narkive permalink

Wie sicher soll dieses Ding sein, und wie hoch ist Ihre Codegröße im Vergleich zu den Kompromissen zwischen Speicherplatz? Benötigen Sie nur fortlaufende Zahlen oder Werte in beliebiger Reihenfolge?

Zwei einfache Ansätze zur Hash-Generierung sind: // Ein zufälliges Bit über einen linearen Kongruenzgenerator abrufen: int random_bit1 (void) {static unsigned langer Samen; seed = seed * magicConstant + 12345; return (seed >> 31); // Oberes Bit verwenden - nicht unteres Bit! }

  int random_bit2 (void) {// Erhalte ein 'zufälliges' Bit über ein lineares Rückkopplungsschieberegister ohne Vorzeichen Long Shifter; if (! shifter) shifter = 1; sonst wenn (Shifter & 1) Shifter = (Shifter>>1); sonst shifter = (shifter>>1); return (Shifter & 1);}  

Um eine vierstellige Zahl zu generieren, verwenden Sie Folgendes:

  int result = 0; int i; für (i = 0; i<30; i ++) // Je höher die Anzahl, desto weniger voreingenommen sind die Ergebnisse {result * = 2; if (Ergebnis > = 10000) Ergebnis - = 10000; Ergebnis + = randomBit ();}  

Beachten Sie, dass beide oben genannten Algorithmen zur Bitgenerierung angepasst werden können, um den n-ten Wert für ein beliebiges n in angemessener Zeit zurückzugeben Code, um das zu tun, wird ein bisschen komplizierter sein. Auf der anderen Seite ist kein Algorithmus schwer rückzuentwickeln.

Wenn Sie nur Werte nacheinander benötigen (dh, nachdem Sie das n-te ausgegeben haben, werden Sie es nie brauchen Um ein Objekt mit niedrigerer Nummer auszugeben, und es macht Ihnen nichts aus, wenn für das Berechnen eines Objekts mit höherer Nummer alle dazwischen liegenden Werte berechnet werden müssen. Es ist möglich, eine gewisse Sicherheit aufzubauen, indem Sie sechs oder so unabhängige Pseudozufallsbitgeneratoren verwenden (möglicherweise Shift) Register mit unterschiedlichen Perioden) und verwenden Sie dann Folgendes:

  int realrandombit (void) {if (randombit1 ()) {if (randombit2 ()) return randombit3 (); sonst return randombit4 (); } else {if (randombit3 ())
return randombit5 (); sonst return randombit6 (); }}  

Beachten Sie, dass für gute Ergebnisse die Verwendung von Zufallsgeneratoren gemischt werden sollte (beachten Sie, dass random3 an zwei verschiedenen Stellen verwendet wird), aber Rückkopplungspfade vermeiden sollten (keiner der Zufallsgeneratoren beeinflussen die Verschiebung von allem, was sie beeinflussen würde, es sei denn, man verfügt über die Werkzeuge, um sie vollständig zu analysieren.

Rev1.0
2013-09-05 12:42:21 UTC
view on stackexchange narkive permalink

Vielleicht interessiert Sie diese Kryptobibliothek. Es wurde unter der GPL v3 veröffentlicht.

Crypto-avr-lib ist eine Reihe von Implementierungen verschiedener kryptografischer Grundelemente. Aufgrund der besonderen Einschränkungen von Mikrocontrollern (sehr wenig Speicherplatz, RAM und Flash reichen von einigen Bytes bis zu einigen KiB) können Referenz- oder "normale" optimierte Implementierungen nicht verwendet werden. Daher versuchen wir, spezielle Implementierungen bereitzustellen, die die extrem begrenzten Ressourcen von Mikrocontroller-Anwendungen berücksichtigen.

Es stehen verschiedene Hash-Algorithmen zur Verfügung:

  • Blake
  • BlueMidnightWish
  • Grøstl
  • MD5
  • SHA-256
  • SHA-1
  • SHA-3 (Keccak)
  • SHABAL
  • Knäuel
  • Twister
  • Whirlpool

Sie können auf die zugreifen vollständiger Code über das Subversion-Repository unter http://das-labor.org/svn/microcontroller-2/crypto-lib.

Weg übertrieben.OP hat eine 4-stellige Anzeige.Und diese Krypto-Hashes sind deutlich langsamer als selbst ein MurmurHash3 (was für einen Mikrocontroller aufgrund der Multiplikation wohl langsam ist).
@bryc: Stimmt, könnte aber trotzdem für andere interessant sein.
Rocketmagnet
2013-09-05 02:14:46 UTC
view on stackexchange narkive permalink
  • Wenn Sie sich wirklich nicht um die Sicherheit kümmern
  • Wenn Sie nur eine Nummer durcheinander bringen möchten

Dann gibt es eine Eine Reihe wirklich einfacher Möglichkeiten, dies zu tun, hier sind zwei, die ich mir vorstellen kann:

  void real_simple_hash (uint16_t x) {SWAP_NIBBLES (FIRST_BYTE (x)); SWAP_NIBBLES (SECOND_BYTE (x)); x ^ = 0xAAAA; return x;}  

Auf einem PIC18 bedeutet dies einen sehr einfachen Code:

  SWAPF x, fSWAPF x + 1, fmovlw 0xAAxorwf x, fxorwf x +1, f  

Es ist ziemlich leicht bei nur 5uS Ausführungszeit auf einem PIC18 mit 10MIPS. Wenn das nicht genug ist, können Sie die Bits in der Nummer mischen. Wiederum auf einem PIC18:

  rrcf x, f; Dann nehmen wir jedes Bit der Quelle wordrlcf y + 1, f; und verschiebe es in eines der Zielbytesrrcf x + 1, frlcf y, f; Es gibt: rrcf x, f; - acht Rechtsverschiebungen von x, rlcf y + 1, f; - acht Rechtsverschiebungen von x + 1, rrcf x + 1, f; - acht Linksverschiebungen von y, rlcf y + 1, f; - acht Linksverschiebungen von y + 1, rrcf x, frlcf y, f; Sie können sie in beliebiger Reihenfolge ausführen , frlcf y, frrcf x, frlcf y + 1, frrcf x + 1, frlcf y + 1, frrcf x, frlcf y, frrcf x + 1, frlcf y, frrcf x, frlcf y + 1, frrcf x, frlcf y, frrcf x, frlcf y, f; Schließlich wird das Ergebnis in y  

gespeichert. Mit einer Ausführungszeit von nur 37uS für denselben PIC18 ist es immer noch recht leicht.

jippie
2013-09-04 21:37:05 UTC
view on stackexchange narkive permalink

Wenn es nicht stark kryptografisch sein muss:

  • Wählen Sie einen zufälligen Schlüssel gleicher Länge in Bits aus.
  • Teilen Sie den Schlüssel zwischen Absender und Empfänger;
  • Absender -Seite: Kryptotext = Klartext-EOR-Schlüssel (Sie können dies byteweise tun ).

Optional:

  • Empfänger -seitiger Klartext = Kryptotext-EOR-Schlüssel.
Das OP möchte keine Nachricht verschlüsseln, sondern benötigt lediglich eine einfache Hash-Funktion. Es gibt keinen "Sender" und "Empfänger". Ich denke nicht, dass diese Antwort überhaupt hilft.
Überspringen Sie also die Empfängerseite und verwenden Sie den Kryptatext als Hash. Ein Hash hat normalerweise die Eigenschaft, dass er nicht auf den ursprünglichen Klartext zurückgesetzt werden kann, aber ich denke nicht, dass das OP etwas dagegen hat.
Außerdem verwandeln Hashes eine Quelle variabler Länge in einen Hash fester Größe.


Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 3.0-Lizenz, unter der er vertrieben wird.
Loading...