0% found this document useful (0 votes)
5 views81 pages

Error Coding For Engineers Houghton Aeditor Instant Download

The document is a reference for 'Error Coding for Engineers' by A. Houghton, which covers the principles and mechanics of error coding in digital systems. It includes various coding techniques, mathematical foundations, and practical implementations to detect and correct errors in data transmission. The book serves as a resource for engineers and students interested in understanding and applying error coding methods without requiring extensive mathematical background.

Uploaded by

bobancomisv0
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views81 pages

Error Coding For Engineers Houghton Aeditor Instant Download

The document is a reference for 'Error Coding for Engineers' by A. Houghton, which covers the principles and mechanics of error coding in digital systems. It includes various coding techniques, mathematical foundations, and practical implementations to detect and correct errors in data transmission. The book serves as a resource for engineers and students interested in understanding and applying error coding methods without requiring extensive mathematical background.

Uploaded by

bobancomisv0
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 81

Error Coding For Engineers Houghton Aeditor

download

https://ebookbell.com/product/error-coding-for-engineers-
houghton-aeditor-21347456

Explore and download more ebooks at ebookbell.com


Here are some recommended products that we believe you will be
interested in. You can click the link to download.

Error Control Coding For B3g4g Wireless Systems Paving The Way To
Imtadvanced Standards Klaus Davideds

https://ebookbell.com/product/error-control-coding-for-b3g4g-wireless-
systems-paving-the-way-to-imtadvanced-standards-klaus-davideds-4303926

Nonbinary Error Control Coding For Wireless Communication And Data


Storage Rolando Antonio Carrasco

https://ebookbell.com/product/nonbinary-error-control-coding-for-
wireless-communication-and-data-storage-rolando-antonio-
carrasco-1224856

Error Correcting Coding And Security For Data Networks Analysis Of The
Superchannel Concept 1st Edition Grigorii Kabatiansky

https://ebookbell.com/product/error-correcting-coding-and-security-
for-data-networks-analysis-of-the-superchannel-concept-1st-edition-
grigorii-kabatiansky-2597780

Error Correction Coding Mathematical Methods And Algorithms Todd K


Moon

https://ebookbell.com/product/error-correction-coding-mathematical-
methods-and-algorithms-todd-k-moon-53645884
Error Control Coding 2nd Edition 2nd Edition Shu Lin Daniel J Costello

https://ebookbell.com/product/error-control-coding-2nd-edition-2nd-
edition-shu-lin-daniel-j-costello-2027864

Error Correction Coding Mathematical Methods And Algorithms 2nd


Edition Todd K Moon

https://ebookbell.com/product/error-correction-coding-mathematical-
methods-and-algorithms-2nd-edition-todd-k-moon-23269180

Errorcorrection Coding And Decoding Bounds Codes Decoders Analysis And


Applications 1st Edition Martin Tomlinson

https://ebookbell.com/product/errorcorrection-coding-and-decoding-
bounds-codes-decoders-analysis-and-applications-1st-edition-martin-
tomlinson-5839528

Error Control Coding From Theory To Practice Peter Sweeney

https://ebookbell.com/product/error-control-coding-from-theory-to-
practice-peter-sweeney-931336

Errorcorrection Coding And Decoding Martin Tomlinson Cen Jung Tjhai


Marcel A Ambroze Mohammed Ahmed Mubarak Jibril

https://ebookbell.com/product/errorcorrection-coding-and-decoding-
martin-tomlinson-cen-jung-tjhai-marcel-a-ambroze-mohammed-ahmed-
mubarak-jibril-59042360
ERROR CODING
FOR ENGINEERS
THE KLUWER INTERNATIONAL SERIES
IN ENGINEERING AND COMPUTER SCIENCE
ERROR CODING
FOR ENGINEERS

A. Houghton
Synectic Systems, Ltd., United Kingdom

SPRINGER. SCIENCE+BUSINESS MEDIA, LLC


Library of Congress Cataloging-in-Publication Data

Houghton, A.
Error coding for engineers / A. Houghton.
p.cm. - (The Kluwer international series in engineering and computer science; SECS 641)
Includes bibliographical references and index.
ISBN 978-1-4613-5589-2 ISBN 978-1-4615-1509-8 (eBook)
DOI 10.1007/978-1-4615-1509-8
1. Signal processing. 2. Error-correcting codes (Information theory) 1. Title. II. Series.

TK5102.9 .H69 2001


005.7'2--dc21
2001038560

Copyright © 2001 by Springer Science+Business Media New York


Originally published by Kluwer Academic Publishers in 2001
Softcover reprint ofthe hardcover Ist edition 2001
AII rights reserved. No part of this publication may be reproduced, stored in a
retrieval system or transmitted in any form or by any means, mechanical, photo-
copying, recording, or otherwise, without the prior written permission of the
publisher.

Printed on acid-free paper.


Table of Contents

Preface IX

1. Introduction 1
1.1 Messages Need Space 1
1.2 The Hamming Bound 4
1.3 The Gilbert Bound 6
1.4 Where Do Errors Come From? 7
1.5 ABrief History of Error Coding 12
1.6 Summary 13

2. A Little Maths 15
2.1 Polynomials and Finite Fields 16
2.2 Manipulating Field Elements 19
2.3 Summary 24

3. Error Detection 25
3.1 The Horizontal and Vertical Parity Check 25
3.2 The Cyc1ic Redundancy Check 27
3.3 Longhand Ca1culation of the CRC 28
3.4 Performance 31
3.5 Hardware Implementation 32
3.6 Table-Based Ca1culation of the CRC 35
3.7 Discussion 39

4. Error Correction by Parity 41


4.1 Correcting a Single Bit 43
4.2 Extending the Message Size 45
5. Error Correction Using the CRC 49
5.1 A Hardware Error Locator 52
5.2 Multiple Bit Errors 53
5.3 Expurgated Codes 54
5.4 The Perfect Golay Code 56
5.5 Fire Codes 63

6. Reed-Muller Codes 67
6.1 Constructing a Generator Matrix For RM Codes 67
6.2 Encoding with the Hadamard Matrix 74
6.3 Discussion 77

7. Reed-Solomon Codes 79
7.1 Introduction to the Time Domain 79
7.2 Calculation of the Check Symbols for One Error 80
7.3 Correcting Two Symbols 83
7.4 Error Correction in the Frequency Domain 88
7.5 Recursive Extension 91
7.6 The Berlekamp-Massey Algorithm 97
7.7 The Fomey Algorithm 100
7.8 Mixed-Domain Error Coding 101
7.9 Higher Dimensional Data Structures 107
7.10 Discussion 118

8. Augmenting Error Coding 119


8.1 Erasure 119
8.2 Punctured Codes 121
8.3 Interleaving 125
8.4 Error Forecasting 130
8.5 Discussion 131

9. Convolutional Coding 133


9.1 Error Correction with Convolutional Codes 135
9.2 Finding the Correct Path 136
9.3 Decoding with Soft Decisions 138
9.4 Performance of Convolutional Codes 140
9.5 Concatenated Codes 141
9.6 Iterative Decoding 142
9.7 Turbo Coding 143
9.8 Discussion 144

vi
10. Hardware 147
10.1 Reducing Elements 147
10.2 Multiplication 149
10.3 Division 153
10.4 Logs and Exponentials 158
10.5 Reciprocal 160
10.6 Discussion 164

11. Bit Error Rates 165


11.1 The Gaussian Normal Function 165
11.2 Estimating the Bit Error Rate 166
11.3 Applications 172
11.4 Discussion 176

12. Exercises 177


12.1 Parity Exercises 177
12.2 CRC Exercises 178
12.3 Finite Field Algebra 180
12.4 Convolutional Codes 183
12.5 OtherCodes 183
12.6 Solutions to Parity Exercises 184
12.7 Solutions to CRC Exercises 186
12.8 Solutions to Finite Field Algebra 192
12.9 Solutions to Convolutional Coding 202
12.10 Solutions to Other Codes 203
12.11 Closing Remarks 208
12.12 Bibliography 208

AppendixA Primitive Polynomials 211


Appendix B The Golay Code 219
Appendix C Solving for Two Errors 223
Appendix D Solving some Key Equations 229
AppendixF Software Library 233

Index 245

vii
Preface

Error coding is the art of encoding messages so that errors can be detected
and, if appropriate, corrected after transmission or storage. A full
appreciation of error coding requires a good background in whole number
maths, symbols and abstract ideas. However, the mechanics of error coding
are often quite easy to grasp with the assistance of a few good examples.
This book is about the mechanics. In other words, if you're interested in
implementing error coding schemes but have no idea what a finite field is,
then this book may help you. The material covered starts with simple coding
schemes which are often rather inefficient and, as certain concepts are
established, progresses to more sophisticated techniques.
Error coding is a bit like the suspension in a car. Mostly it's unseen, but the
thing would be virtually useless without it. In truth, error coding underpins
nearly all modem digital systems and without it, they simply couldn't work.
Probably like some car suspensions, the elegance of error coding schemes is
often amazing. While it's a bit early to talk about things like efficiency, two
schemes of similar efficiency might yield vastly different performance and,
in this way, error coding is rather 'holistic'; it can't be treated properly
outside of the context for which it is required. WeIl, more of this later. For
now, if you're interested in whole number maths (which is actually really
good fun), have a problem which requires error coding, are an undergraduate
studying DSP or communications, but you don't have a formal background in
maths, then this could be the book for you. Principally, you will require a
working knowledge ofbinary; the rest can be picked up along the way.

x
Chapter 1

INTRODUCTION

The chapter deals with an overview of error coding, not especially in terms
of what' s been achieved over the years or what is the current state of the
subject, but in pragmatic terms of what' s undemeath it that makes it work.
The maths which surrounds error coding serves two key purposes; one, it
shows us what can theoretically be achieved by error coding and what we
might reasonable have to do to get there and, two, it provides mechanisms
for implementing practical coding schemes. Both of these aspects are,
without doubt daunting for anyone whose principal background is not maths
yet, for the engineer who needs to implement error coding, many of the
practical aspects of error coding are tractable.

1.1 Messages Need Space

Space is at the heart of all error coding so it seems like a good place to
start. If I transmit an 8-bit number to you by some means, outside of any
context, you can have absolutely no idea whether or not what you receive is
what I sent. At best, if you were very clever and knew something about the
quality of the channel which I used to send the byte (an 8-bit number) to
you, you could work out how likely it is that the number is correct. In fact,
quite a lot of low-speed communication works on the basis that the channel
is good enough that most of the time there are no errors. The reason that you

A. Houghton, Error Coding for Engineers


© Kluwer Academic Publishers 2001
2 1.1 Messages Need Space

cannot be certain that what you have received is what I sent is simply that
there is no space between possible messages. An 8-bit number can have any
value between and inc1uding 0 and 255. I could have sent any one of these
256 numbers so whatever number you receive might have been what I sent.
You've probably heard of the parity bit in RS232 communications. If not, it
works like this. When you transmit a byte, you count up the number of Is in
it (its weight) and add a ninth bit to it such that the total number of Is is even
(or odd; it doesn't matter which so long as both ends of the channel agree.)
So we're now transmitting 8 bits of data or information using 9 bits of
bandwidth. The recipient receives a 9-bit number which, of course, can have
512 values (or 2n where n is the number of bits). However, the recipient also
knows that only 256 of the 512 values will ever be transmitted because there
are only eight data bits. If the recipient gets a message which is one of the
256 messages that will never be transmitted, then they know that an error
has occurred. In this particular case, the message would have suffered a
parity error.
In essence, what the parity bit does is to introduce some space between
messages. If a single bit changes in the original 8-bit message, it will look
like another 8-bit message. If a single bit changes in the 9-bit, parity-encoded
message, it will look like an invalid or non-existent message. To change the
parity-encoded message into another valid message will require at least 2
bits to be flipped. Hopefully this is really obvious and you're wondering why
I mentioned it. However space, in one form or another, is how all error
coding works. The key to error coding is finding efficient ways of creating
this space in messages and, in the event of errors, working out how to correct
them.
Space between messages is measured in terms of Hamming distance (d).
The Hamming distance between two messages is a count of the minimum
number of bits that must be changed to convert one message into the other.
Error codes have a special measure called dmino d min is the minimum number
of bits that must be changed to make one valid message look like another
valid message. This, ultimately, deterrnines the ability of the code to detect
or correct errors. Every bit-error that occurs increases the Hamming distance
between the original and corrupted messages by one. If terrors are to be
detected then

dmin > t. (1.1)

In the case of the simple 8-bit message with no parity, dmin = 1, so t = O.


However, with the addition of a parity bit, dmin increases to two, so t = 1, i.e.
CHAPTER 1. INTRODUCTION 3

we can reliably detect a single-bit error. Should we want to be able to


correct messages, then (1.1) is modified to (1.2), below.

dmin > 2t. (1.2)

Clearly parity, as it has been presented above, cannot correct errors. So


where does (1.2) come from? Error correction works by finding the nearest
valid message (in terms of d) from the corrupted message. Using the simple
ca se of parity checking, dmin = 2. A single-bit error will change a valid
message into an invalid message which has a d of 1 from it. However,
because dmin is only two, there will be other messages which are also only
one bit away from the invalid message. In fact, any one of the nine bits could
be changed in the invalid message to create a valid message. The problem is
that there are several messages equally close to the corrupted message and
we have no means to choose between them. If dmin was three, however, (i.e. >
2t) the original message would, as before, be one bit away from the invalid
message, but no other valid message could be nearer than two bits away. In
this case, there is a nearest candidate.
A good way to visualize this is to draw 2n circles on a piece of paper
(where there are n message bits) and fill in 2k of them (where k bits are data
or information) as evenly spread over the page as possible. The circles
represent all possible messages, while those that are filled in are the sub set
of valid messages. Figure 1.1 is my attempt at this.
o
o o • o

0/
o 2n message points (circIes)

o
° ~=~, ° o
o . . \ () 0/// o
o 0 . .· · · · · . . 0 .'
k ./
.... 2 valid messages ................. . o
o o ......... 0 (filled circIes)
.................................... 0 o o
• o o o
Figure 1.1 Valid data points within the total message space.
4 1.2 The Hamming Bound

Starting at a valid message, introduce an error by moving away to the


nearest circle. Each time you add an error bit, move further away from the
starting message. EventuaIly, the correct (starting) message will no longer be
the nearest filled in circle. When this happens, the capacity of the code has
been exceeded and an attempt at correction will make matters worse. This
illustration is actuaIly the projection of an n-dimensional problem onto a 2-
dimensional space (your paper) and so is rather approximate. It none-the-Iess
describes quite weIl the principle.

1.2 The Hamming Bound

The use of n and k, above, leads to the idea of (n, k) or (n, k, t) codes,
another way in which error codes are often defined. n is the total number of
message bits, so there are 2n possible messages for the code, while k defines
how many of those bits are data or infonnation bits. So out of the 2n
messages, 2k will be valid. The job of the error code is to spread the 2k valid
messages evenly across the 2n message space maximizing dmin • A question
you might reasonably ask is, is there a relationship between t, n and k?
Another way of putting this might be to wonder how many bits of
redundancy (n - k) must be added to a message to create a t-error correcting
code. There is a pragmatic and a mathematical way of considering this
question. It's useful to start at the mathematical end since, if you can acquire
a broad understanding of what's involved in error coding right at the start, it
aIl makes more sense later on. Here goes then:
n, k and t are a littIe intertwined and it's easiest to choose three values and
see if they can be made to satisfy certain constraints. For an example,
consider the possibility of a (7, 4, 1) code. Could such a thing ex ist? There
are 16 valid messages (24) in a pool of 128 possible messages (27) and we
want to correct I-bit errors. Each valid message must be surrounded by a sea
of invalid messages for which d <= t. For correction to be possible, no other
valid messages are allowed to share these unless, for them, d > t. So in this
example, each of the 16 messages must have seven surrounding messages of
d = 1 that are unique to them to permit correction. Each valid message
requires 1 (itself) + 7 (d = 1 surrounding) messages. We need, therefore, 8
messages per valid message and there are 16 valid messages giving 8 x 16 =
128 messages in total. In this case there are exactly 128 available so, in
principle at least, this code could exist. This limit is caIled the Hamming
bound and codes (of which there are a few), which satisfy exactly this bound
CHAPTER 1. INTRODUCTION 5

are called perfect codes. For most codes 2n is somewhat greater than the
Hamming bound.
In general terms, an n-bit message will have
n!
(1.3)
d!(n-d).

messages that are d bits distance from it. This is simply the number of
different ways that you can change d bits in n. So, for a terror correcting
code, the Hamming bound is found from

which simplifies to

(1.4)

If you can visualize n-dimensional space, then each message represents a


point in this space. Around each point, there is a surface of other points with
radius 1 bit. Around that surface there is another of radius 2 bits and so forth
up to n bits. (1.3) teIls us how many points exist in each of these surfaces.
Some codes which satisfy exact1y the Hamming bound inc1ude (3, 1, 1), (5,
1,2), (7, 4, 1), (7, 1,3), (9, 1,4), (11, 1,5), (13, 1,6), (15, 11, 1), (15, 1, 7),
(17, 1, 8), (23, 12, 3), (90, 78, 2). Most of these contain only one data bit so
the two valid messages (2 1) might be all zeros and all ones. Codes with the
form (2 m - 1, 2m - m - 1, 1) such as (15, 11, 1) are known as Hamming codes
and we'll see how these are constructed later. The code (23, 12, 3) is called
the Golay code and, according to Golay, there is no solution to the code (90,
78,2).
In some ways perfect codes are the most efficient codes since there are
absolutely no wasted points in the 2n message space. However, this has its
drawbacks. With perfect codes all received messages (whether valid or in
error), will decode to a solution. There are no invalid messages more than t-
bits away from a valid message. This means that if more that t bit-errors
occur, there is no way of telling. The Golay code, which will correct up to
three bit-errors, is usually extended to a (24, 12,3) code by adding an overall
parity bit. While it can still only correct three errors it can now detect the
presence of four.
6 1.3 The Gilbert Bound

1.3 The Gilbert Bound

The Hamming bound is one extreme end of the (n, k, t) relationship,


packing the most capability into the least redundancy. At the other end is
something called the Gilbert bound. This bound gives the smallest size of the
message space (2 n) that absolutely guarantees that there will be a t-error
correcting code for k data bits. It's trivial to construct working codes at this
end of the (n, k, t) relationship although that doesn't mean they're any good.
The Gilbert bound works on the following argument. If we want a t-error
correcting code then we choose at random from the 2n message space a valid
code. The message and all messages within 2t bits distance of it are deleted.
The next message is chosen from the remaining pool and all messages within
2t of it are deleted, and so forth. Each valid message thus requires

Ld!(nn'-.d)
21

d=O

messages out of the total pool. If there are k data bits then a total of

2k XL 21
n.
,

d=O d!(n - d)

messages are needed so the Gilbert bound is generated from (1.5)

L
21
n.
,
< 2 n- k (1.5)
d=O d!(n - d) -

Most error codes sit somewhere between these bounds which means that
often, even though the capacity to correct errors may have been exceeded,
the code can still detect unrecoverable errors. In this instance the received
error message will be more than t from any valid code so no correction will
be attempted.
So what about the pragmatic approach? During decoding the extra bits
added to a message for error coding give rise to a syndrome, typically of the
same size as the redundancy. The syndrome is simply a number which is
usually 0 if no errors have occurred. If terrors are to be corrected in a
message of n bits then the syndrome must be able to identify uniquely the t
bit-error locations. So in n bits, there will be
CHAPTER 1. INTRODUCTION 7

1: n'.
t

d=O d!(n - d).

possible error combinations (including the no-error case). The syndrome


must have sufficient size to be able to identify all of these error
combinations. If the syndrome is the same size as the redundancy (n - k),
then to satisfy this requirement gives

1:t
n.
,
~ 2 n- k
d=O d!(n - d).

which is, of course, the Hamming bound. Another way of viewing this is to
consider the special case of messages where n = 2i - 1 (i is some integer). At
least i bits will be needed to specify the location of one bit in the message.
For example, if the message is 127 bits then a 7-bit number is required to
point to any bit location in the message (plus the all-zero/no error result). So
for terrors, at least t x i check bits will be needed. We can compare this
result with the (15, 11, 1) code. To find one error in 15 bits needs 1 x 4 = 4
check bits which there are. If you try this approach with the Golay code, you
find that 15 check bits should be needed as opposed to the 11 that there
actually are. See if you can work out why this is and repeat the calculation
for the (90, 78, 2) code.
A few more basic measures can be derived from (n, k, t) codes.
Redundancy is the name given to the extra bits (r) added to a message to
create space in it. The amount of redundancy added gives rise to a measure
called the coding rate R which is the ratio of the number of data bits k,
divided by the total bits k + r (= n). In percent, R gives the code ejficiency.

1.4 Where do Errors Come From?

Errors arise from a number of sources and the principal source which is
anticipated should, at least in part, determine the code that is used. There are
two main types of error which are caused by very different physical
processes. First there are random errors. Any communications medium
(apart perhaps from superconductors which, as yet, are not ubiquitous), is
subject to noise processes. These may be internal thermal and partition noise
sources as electrons jostle around each other, or they may be the cumulative
8 1.4 Where Do Errors Come From?

actions of extemal electromagnetic interference being picked up en route.


This kind of noise gives rise to the background hiss in your hi-fi system or
the fuzzy haze on the TV screen in areas with poor reception. Noise like this
typically has what is called a Gaussian PDF (probability density function).
So travelling down the communications cable is the data (ls and Os) plus
noise. When the data (plus noise) reaches its destination, a receiver circuit
has to decide whether the data is 1 or 0 (crudely speaking). The noise
content adds a little uncertainty into this process and leads ultimately to the
addition of random errors.
The great thing about random errors is that they can be precisely modelIed.
You can predict exactly how likely an error is, how many will occur each
hour and so forth. Unfortunately, you can never predict which bit it'll be.
Taking a very simple example, suppose that a data 1 is represented by +1
volt and a data 0 by -1 volt on a piece of wire. The receiver will decide on
the current state of the signal by comparing it with 0 volts. Figure 1.2
illustrates the example.

lV

Figure 1.2 Gaussian PDF.

The curves about the ±1 volt markers are the Gaussian function (also
called the normal function) which has the form in (1.6), below.

(X_X)2
1 22
---==e (J (1.6)
(j.J27r

cr is the standard deviation of the function, while xis the mean. The curve
describes in terms of probability, what the received signal will be. The total
area under the curve is 1 so the received signal must have some value. In
this example, we could calculate how likely a 0 would be of being
misinterpreted as a 1 by measuring the area under the solid curve that falls to
CHAPTER 1. INTRODUCTION 9

the right of the 0 volt decision threshold. Suppose it was 0.001, or Ihooo. This
means that one in one thousand Os will be read as a 1. The same would be
true for Is being misread as Os. So all in all, one in five hundred bits
received will be in error giving a bit error rate (or BER) of 0.002. The BER
can be reduced by increasing the distance between the signals. Because of
the shape of the PDF curve, doubling the 0/1 voltages to ±2 volts would give
a dramatic error reduction.
Channe1s are often characterised graphically by showing BER on a
logarithmic axis against a quantity called Eh/No. This is a normalized
measure of the amount of energy used to signal each bit. You can think of it
like the separation of the Os and 1s in Figure 1.2, while the noise processes
which impinge themselves on the signal control the width (or 0") of the
Gaussian PDF. The greater Eh/No, the smaller the BER. Eh/No can be
thought of in a very similar way to SNR or signal to noise ratio. Figure 1.3
show an example of bit error rate against signal strength

o 2 3 4 5 6 7
Or---~--~--~--~--~--~~
Coding loss
·1

ffi ·2
m
C5' ·3
(;
0-4 Coding gain
..J
·5
·6

Eb/NO (dB)

Figure 1.3 BER against Eh/No.

The solid line represents an uncoded signal whereas the dotted line is the
same channel, but augmented by error coding. This gives rise to an
enormously important idea called coding gain. At very low powers (and
consequently high error rates), the addition of error coding bits to the
message burdens it such that an Eh/No of Figure 1.3 in the coded channel,
gives the same performance as the uncoded signal with an Eh/No of O. The
reason is that to get the same number of data bits through the channel when
coded, more total bits must be sent and so more errors. Because the errors
rates are high, the coding is inadequate to offset them (t is exceeded), so
10 1.4 Where Do Errors Come From?

we're actually worse off. However, at signal powers of 2, the coded and
uncoded channels have similar performance while above 2, the coded
channel has a better performance. The early part of the graph represents
coding loss, while the latter, coding gain. So why is this important?
If a particular system requires aBER of no greater than one error in 105,
then an uncoded channel in this example will need an Eb / No of 5. However,
the coded channel can provide this performance with an E b / No of only 4, so
the code is said to give a coding gain of IdB (Eb / No). Put this in terms of a
TV relay satellite and it starts to make good economics. Error coding can
reduce the required transmitter power or increase its range dramatically
which has an major impact on the weight and lifetime of the satellite.
Approximately, when error coding is added to a signal, the two distributions
in Figure 1.2 get closer together since, for the same transmitter power, more
bits are being sent. Normally, this would increase the BER. However, the
effect of adding error coding reduces the widths (a) ofthe distributions such
that the BER actually decreases.
Before leaving random errors, there is another aspect to them which has
been usefully exploited in some modem coding schemes. When a random
error occurs, the nature of the Gaussian PDF means that the signal is
increasingly likely to be near to the decision boundary (0 volts in this
example). Rather than make a straight-forward 1/0 decision, each bit can be
described by its probability of being a 1 or a 0 (a soft decision). Figure 1.4
shows the typical soft output.

-0.5 o 0.5 1 1.5


x
Figure 1.4 Probability distribution with soft boundaries.
CHAPTER 1. INTRODUCTION 11

A random error that turns a 0 into a 1 is statistically likely to have a low


probability of being a 1. In simple terms, the signal undergoes an analogue to
digital conversion rather than slicing so that instead of outputting a 0 or 1,
the decoder might output a value between 0 and 7. A good 0 would be 0,
while a good 1 would be 7. A weak 0 would be 3, while a weak 1 would be
4. Overall (although not exclusively), random errors will give rise to weak 1s
and Os. If the decoder detects an error, the most likely suspects will be the
weaker bits. In essence, what this process does is to increase the resolution
of d from whole bits to fractions of bits. This is called soft decision decoding
and, although not directly relevant to all codes, it helps error coding to
approach its theoreticallimits.
The second main type of error is called a burst error. A burst error is
characterized by b - 2 bits which may or may not be in error, sandwiched in-
between two bits that definitely are in error, and preceded by at least b error-
free bits. Errors of this kind typically come from electromagnetic transients
caused by heavy electrical machinery switching. Deep scratches on the
surface of a CD or other media defects might also cause burst errors. These
are unpredictable in every way and will normally be handled very differently
from random errors. An everyday example of the source of burst errors could
be the clicking picked up on the radio when a badly suppressed car engine is
running nearby. Returning to the example of a damaged or imperfect CD,
many successive bits may be lost in one go. An error code capable of
handling this kind of data loss would be excessively large and complex so
other processes may be used in conjunction with error coding including
interleaving.
If you're on of those people who read the technical specs. on your hi-tech
appliances in order to compare notes with friends, you'll doubtless have
noticed that your CD player boasts "cross-interleaved Reed-Solomon
coding" (they all do!) Cross-interleaving is a relatively simple process wh ich
decorrelates or spreads errors out. A media defect can give rise to large
gouts of lost data so it is necessary to divide the error in order to conquer it.
In approximate terms, data is read into a memory row by row and each row
is error coded. It is then written onto the media in a colurnn-wise basis. Upon
reading, the data is arranged back into the memory colurnn-wise, ready to be
decoded row-wise. In the event of a large error, even if a whole colurnn is
lost, there will still be only one error in each row, wh ich can be easily
corrected. Devising efficient spreading algorithms is quite an art in itself and
we'll visit this later. Question: Will interleaving help when combatting
random errors?
12 1.5 ABrief History of Error Coding

1.5 ABrief History of Error Coding

Modem error coding, while based on maths that was discovered (in some
cases) centuries ago, began in the late forties with most of the major
innovations occurring over the fifties, sixties and seventies. In 1948 Claude
Shannon proved that, if information was transmitted at less than the channel
capacity then, it was possible to use the excess bandwidth to transmit error
correcting codes to increase arbitrarily the integrity of the message. The race
was now on to find out how to do it.
During the early fifties Hamming codes appeared, representing the first
practical error correction codes for single-bit errors. Golay codes also
appeared at this time allowing the correction of up to three bits. By the mid-
fifties Reed-Muller codes had appeared and, by the late fifties, Reed-
Solomon codes were born. These last codes were symbol, rather than bit,
based and underpin the majority of modem block coding. With block codes,
encoding and decoding operate on fixed sized blocks of data. Of necessity,
the compilation of data into blocks introduces constraints on the message
size, and latency into the transmission process, precluding their use in
certain applications.
It is important to remember that, while the codes and their algebraic
solutions now existed, digital processing was not what it is today. Since
Reed-Solomon codes had been shown to be optimal, the search was shifted
somewhat towards faster and simpler ways of implementing the coding and
decoding processes to facilitate practical systems. To this end, during the
mid-sixties, techniques like the Fomey and Berlekamp-Massey algorithrns
appeared. These reduced the processing burdens of decoding to fractions of
what had been previously required, heralding modem coding practice as it is
today.
Almost in parallel with this sequence of events and discoveries was the
introduction in the mid-fifties, by Elias, of convolutional codes as a means of
introducing redundancy into a message. These codes differed from the others
in that data did not need to be formatted into specific quantities prior to
encoding or decoding. Throughout the sixties various methods were created
for decoding convolutional codes and this continued until1967 when Viterbi
produced his famous algorithrn for decoding convolutional codes which was
subsequently shown to be a maximum-likelihood decoding algorithm (i.e.,
the best you could get).
The eighties contributed in two key ways to error coding, one of which
was the application of convolutional coders to modulation, creating today's
reliable, high-speed modems. Here the error coding and modulation
CHAPfER 1. INTRODUCTION 13

functions ceased to be separate processes but were integrated into a single


system. The mathematical space generated in messages by error codes was
translated into modulation space. The second was the application of so-
called algebraic geometry to Reed-Solomon coding. This step created a class
of codes called Quasi-Maximum Distance Separable codes, based on elliptic
curves. Today, much attention is being given to Turbo codes. These are a
class of iteratively decoded convolutional codes which appear to be
approaching the theoreticallimits of what error coding can achieve.
Clearly error coding as we know it started life in the fifties but, curiously,
the first example of both the need for and the application of error coding
could go back as far as 1400BC. In 1890, the Russian mathematician Dr Ivan
Panin found a rigorous coding scheme that permeates the length and breadth
of the bible. The bible's authors must have feIt the information was
important enough to warrant protection of some sort and, presumably with
this in mind, built a very complex heptadic (based on sevens) structure into
it. Since both the Old Testament (in Hebrew) and the New Testament (in
Greek) share characters which are both letters and numbers, each word also
has a numerical value. Apparently, only a simple test is required to see if a
book complies with the code and, where two manuscripts are found to differ,
it is easy to see which is the more accurate (according to the code).
Coding of this nature is asymmetric. While it is simple to decode, the
encoding process is unknown to date and hasn't been reproduced on any
significant scale. Panin, however, used the code to create his own version of
parts of the bible, correcting any deviations from the heptadic structure.

1.6 Summary

While the introduction is in fairly broad brush-strokes, the ideas covered


are central to error coding. Space, in one form or another, is what makes
error coding possible. The Hamming and Gilbert boundaries link the amount
of space required to the message size and error correcting capability. The
maths that I included at this point needs a little thought. If equations like
(1.3) are new to you, work through a few simple examples with small
numbers that are manageable. Take, for example, four red snooker balls and
three blue. See how many different ways you can arrange the blues between
the reds then compare your results with

~=35.
3!4!
14 1.6 Summary

You've actually calculated the number of different ways that you can
change three bits in a total of seven. Take any 7-bit message and there are 35
other messages that are 3 bits distance from it. At this point, you might even
be able to construct an error code using the Gilbert bound coupled with a
random code selection and deletion process.
Error types and sources have been considered, leading into processes
which can augment error coding like soft-decision decoding and
interleaving. When all these ideas are brought together, some spectacular
results emerge. Messages that come back from deep space probes can be
buried deeply in noise and yet, with error coding, the data are still
recoverable. Digital TV places tight constraints on acceptable BER and yet,
with error coding, it's possible without enormous transmitter power. CDs and
especially DAT (Digital Audio Tape) players simply wouldn't work without
error coding. Systems like modems combine error coding with signal
modulation to provide communications almost at the limit of what is
theoretically possible. So what we need now are some practical schemes for
implementing error coding and decoding.
Chapter 2

A LITTLE MATHS

This chapter introduces some of the maths that is required in order to


perform certain block coding schemes. Treatment is from a practical, rather
than theoretical, point of view, always with hardware implementation in
mind. No attempt is made to prove the ideas considered here since there are
plenty of exceHent texts on the subject and (mathematicians: look away now)
generaHy in engineering, "if it works twice, it's a law". No one who has ever
used maths for anything practical can have failed to notice how amazing it is
that diverse approaches to problems converge upon common answers. Logic,
of course, predicts this and this is also why mathematicians go to great
lengths to prove that "it wasn't a fluke and it'H work more than twice".
Whole number maths, which underpins much error coding, is one of those
amazing subjects which opens up a whole vista of possibilities for engineers.
Imagine being able to perform all sorts of complex operations using only a
finite set of numbers, and never having to worry about fractions! Hopefully
this chapter will be fun, rather than onerous and, if you've never heard of
finite fields are, you're in for a pleasant surprise.

A. Houghton, Error Coding for Engineers


© Kluwer Academic Publishers 2001
16 2.1 Polynomials and Finite Fields

2.1 Polynomials and Finite Fields

In error coding, certain ideas, terms and mathematical operations appear


quite frequently. Since this is so, these ideas are introduced early on. At first,
they'll seem quite abstract but, once a few coding examples are worked
through, it'll all make good sense. Inevitably some ideas will get expanded
later on but a few basic mIes now provide a good foundation to work from.
Generally, operations are executed modulo-2. This means that many
functions can be realised by eXclusive ORing, making implementation in
hardware trivial. As a result there is no need to be concerned with negative
numbers since 1 + 1 = 0, so 1 = -1. Also, much of the maths needed operates
over finite fields. Finite fields are closed sets of numbers constructed using
things called primitve polynomials or generator polynomials (GP). Any
mathematical operation performed over a finite field will result in a number
which is in the field. There is a certain amount of terminology and notation
which surrounds this type of whole-number maths and it' s useful to acquire
at least a superficial recognition of it.
For reasons of generality, numbers are often expressed in the form

for example. Since we will only be dealing with binary, x is simply 2. The
above example could be written

However, while these representations may be interchangeable, the form used


must reflect the operation that you are performing. For example, to multiply
two such polynomials (as they are called), say 10101 and 110010, it would
be wrong to assume that the answer was 21 x 50 (=1050). This operation
would have to be done modulo-2 as
CHAPTER 2. A LITTLE MATHS 17

= 111101 1010 (or 986)

(don't forget, 1 is xo). Usually, the result would have been

but where there is an even number of similar terms the result is zero (i.e.
1 + 1 = 0) so the x 5 term goes since x5 + x5 = (1 + 1)x5 • It may be that the
finite field we're using doesn't contain elements as high as x9 in which case
the ans wer is modified further, using the generator polynomial to 'wrap' the
higher order terms back into the field. We'll see how this operates shortly.
A finite field is constructed using a generator polynomial (GP) which is
primitive. This means that it has no factors (or is irreducible). Consider the
following:

(x2 +x+ 1)(x+ 1)


expandsto

which simplifies to

x 3 + 1 is not primitive because it has at least two factors, x 2 + x + 1 and


x + 1. So a primitive polynomial has no factors, and some examp1es inc1ude:

x 2 +x + 1 = 0,

x 3 + X + 1 = 0, x 3 + x 2 + 1 = 0,

x5 + x4 + i + x + 1 = O ...

The set of numbers which the GP describes contains elements one bit less in
length than the GP itself. Technically speaking, the degree of the elements
(their highest power or x) is one less than that of the GP. So the field that
x4 + x + 1 forms, for example, contains elements which inc1ude bits up to x 3
18 2.1 Polynomials and Finite Fields

but no higher. You may already be familiar with finite fields but in a
different guise. Pseudo random binary sequences are sometimes generated in
the same way as finite fields. PRBSs are sequences of numbers which repeat
in the long term, but over the short term, appear random.
Finite fields are often referred to in the form GF(2 n ). The G stands for
Galois who originated much of the field theory, while the F stands for field.
The 2 means that the field is described over binary numbers while n is the
degree of the GP. Such a field has, therefore, 2n element (or numbers) in it.
Taking a small field, GF(2\ we'll use the polynomial x 3 + x + 1 = O. To
ca1culate the field we start off with an element called a wh ich is the
primitive root. It has this title because all elements of the field (except 0) are
described uniquely by apower of a. In this ca se a is 2, 010 or x. For any
finite field GF(2n), a 2n - 1 = aO = 1. What's special about these fields is that
the elements obey the normal laws of maths insofar as they can be added,
multiplied or divided to yield another member of the field. Table 2.1 shows
how the field is constructed.

Table 2.1 GF(2 3 )

a Calculation Numeric value

al x ::: X 010 (2)


a2 ::: X.x ::: ~ ::: 100 (4)
a3 x.x.x ~

there is no term ~ but, from the primitive polynomial ~ + x + 1 ::: 0, we can see that
~::: X + 1, remembering also that 1::: -1. Substituting 'folds' ~ back into the bottom 3
bits.

a3 ~ ::: x+I ::: Oll (3)


a4 a.a3 ::: x.(x + 1) :::x2 +x ::: 110 (6)
a5 a.a4 ::: x.(~+x) :::~+~ ::: (x+ 1) +~ ::: 111 (7)
a6 a 2.a4 ~.(~ + x) ::: x.(x + I) + (x + I) ::: ~ + 1 101 (5)
a7 ::: a.a6 ::: x.(~ + 1) :::~+~ :::(x+l)+x 001 (1)
a8 a.a7 ::: a.I :::a

Notice that a 7 = aO ( = 1) and sequence starts to repeat (i.e. a 8 = ( 1). A


reducible or non-primitive polynomial does not produce this maximal
sequence. For example, Table 2.2 repeats the above ca1culations using
i + x2 + X + 1 =0 which has three equal factors, (x + 1).
CHAPTER 2. A LITTLE MATHS 19

Table 2.2 Generating a sequence using a non-primitive polynomial

a Calculation Numeric value

a1 x = 010 (2)
a2 = X.x ~ = 100 (4)
a3 = x.x.x = ~

thistime, x3=~+X+ 1 so

a3 = x3 ~+x+1 = 111 (7)


a4 = a.a3 = x.(~ + x + 1) = ~ + x 2 + x =1 001 (1)
a5 a.a4 x.(l) = x = a1 = 010 (2)

and the cycle repeats. This time, we have not generated all non-zero elements with three
bits. In fact, there are three cycles, corresponding to the three factors of ~ + ~ + x + 1 = O.
Exactly which one is generated depends on the starting conditions. The above cycle
contains 2, 4, 7, 1. Starting with a value not represented here, say 3, then
?
a' x+1 = Oll (3)
?
a.a' = x.(x+ 1) = 110 (6)
a.a?+I= x.(x2 +x) = = x+l = Oll (3)

generating a smaller cycle containing 3 and 6. Starting with the one remaining unused
number, 5, then

a7 = x2 +1 = 101 (5)
a.a? x.(~ + 1) ~+x = ~+ 1 101 (5)

Appendix 1 lists some primitive polynomials for you to experiment with.

2.2 Manipulating Field Elements

fu order to do useful things with finite fields it is necessary to understand


how to use the elements. This, perhaps, is where whole number maths starts
to depart from the traditional concept of mathematical operations although,
surprisingly, it's not difficult with a little practice. Using the field in Table
2.1 consider addition (which is also subtraction.) To add two elements,
simple bit-wise XOR; for example
20 2.2 Manipulating Field Elements

or in binary 100
LUEB
011

Multiplication and division can be performed in two ways. First, using


powers.

Multiplying in this way is simply a matter of adding powers modulo-7.


However, the same result may be achieved using the bit patterns of the field
elements. Taking the second example

first, eliminate common terms

now use the GP to bring x 4 back into the field

= xx3 + X = x(x + 1) + x

sb we've achieved the same result. For division, consider a / a 5 or


CHAPTER 2. A LITTLE MATHS 21

To evaluate this we need to examine long division over finite fields. This
is not altogether dissimilar to normallong division and is best attempted bit-
wise. Rearranging the problem gives

010
1 1 1

Step 1 involves aligning the most significant set bit of the denominator
with the most significant set bit in the numerator (assuming both are non-
zero). So the sum above becomes
1 (result)
0 f 0 ~; ~

(align) \1i 1 1 (f)


0 1 1 (remainder)

and a 1 is placed in the result, coinciding with the least significant bit
position of the denominator. A remainder is ca1culated by exc1usive-oring
the denominator with the numerator. When the remainder is zero, the
division is complete. The two vertical lines represent the valid range of the
result which, over this field, inc1udes x 2 , Xl and xo. Now you can see that the
first ca1culated bit of the result falls in the position X-I, out of range. To
prevent this from happening, we can use the fact that 1 = x + i, from the
generator polynomial.
In table 2.1, you may recall that the GP was used to change x 3 into x + 1 or
= (13. For numerical purposes, we could think of i as (13 and x4 as (14 and so
on for any Xi. For example, we saw, in the previous multiplication, how x 4
was brought back into the field using the substitution x(x + 1). This can also
be done for negative i. In the division above, there is a result and remainder
term in the [ I column. In just the same way that x4 can be thought of as (14
even though it is not strictly in the field, so X-I can be thought of as (1-1, or (16
=~ + 1 . Rearranging the GP, we have

so

The GP can, therefore, be used to move bits both to the right and the left in
order to bring them back into the field. Rearranging, the ca1culation above
becomes
22 2.2 Manipulating Field Elements

0 1 1 (result)
0 0
(align) 1 1 EB
0 1 (remainder)

However, continuing the calculation in this way does not lead to a solution
since, in this case, it is not possible to get a zero remainder. Instead, the
division can be performed as follows:

h 18
16 14 15
11 h 13 (result)
0 1 0 (X
1 0 1 M" 0 0 (X (becomes)
1 1 11 EB
1 0 0 (X3 (remainder)
1 1 12 EB _ (X5

1 1 0 (X4 (remainder)
_ (X5
1 1 h
0 o 1 aO (remainder)
1 0 1A('0 (x0 (becomes)
1 1 14 EB _ a5

1 0 0 (X2 (remainder)
1 1 15 _ a5

0 1 1 a 3 (remainder)
1 0 1 A(' 0 1 a 3 (becomes)
1 1 16 EB _ a5

1 0 0 a 3 (remainder)
1 1 h EB _ a5

1 1 1 (X5 (remainder)
1 1 18 _ (X5

0 0 0 0 (remainder)

To summarise, when dividing would result in a bit in the result to the right
of xO, the left-most 1 in the current numerator is replaced by substitution
using the GP. As a result of this iterative solution, the result (the top three
rows) looks a bit confusing. However, the bits are summed vertically
modulo-2 to give 011 or a 3, the correct result.
CHAPTER 2. A LITTLE MATHS 23

Logs and anti-logs of elements are important and useful functions.


Generally theyare most easily accomplished using look-up-tables. However,
over large fields or in low-cost microcontroller-based solutions, this may not
be practical. If look-up-tables cannot be used then some slower algorithmic
solutions must be found. The simplest way to calculate the anti-log or
exponential of a value, say i, is to multiply 1 (ci) by a, i times. First, of
course, i must be brought into the range 0 to 2n - 2 for the field GF(2n ),
either by using the modulo function or addinglsubtracting 2n - 1 as
appropriate. Logs can be found in a similar way by counting how many times
the operand must be multiplied by a- I until the result is 1 (ao).
Over a large field this will be quite slow so ways of speeding up the
operation are required. Considering first anti-logs, it is possible to construct
a circuit or algorithm which calculates the square of an element. Essentially
this is a multiplier with its inputs connected together. The circuit is fed back
into itself via a register and preloaded with a. Clocking it n times produces
the sequence
Z 4 8
a,a,a,a ...

and so on up to a zn -1 • A second multiplier-accumulator (MAC) is required


wh ich is initialised to 1. The inputs to this MAC are itself and the square
generator. The value i to be anti-Iogged is arranged in a shift (right) register
which is clocked synchronously with the square generator. If the output from
the shift register is 1, the MAC is latched, otherwise its contents remain
unchanged. After n clocks (maximum), the MAC will contain the bit pattern
of a i• This gives an exponential speed-up of the original algorithm and is
illustrated in Figure 2.1, below.

Clock
Figure 2.1 An anti-logging circuit.
24 2.3 Summary

A speeded up logging algorithm works by noting that the first n elements


of a field GF(2n ) have a weight of only 1. For example, the field GF(2 3) has
0.0 = 001, 0. 1 = 010 and 0.2 = 100. Any value a i can be changed into the form
rf!ab><n, where a = i MOD n and b = i DIV n over GF(2n ). To find the log, ai
is multiplied by a.-n (counting as we go) until the result has a weight of only
1. The log will be n times the number of counts (b) plus the bit position of
the remaining single bit (a). A worst case of (2n - 2)/n steps will, therefore,
be needed.

2.3 Summary

Obviously this will seem a little out of context at the moment since there
have been no examples yet, to hang these ideas on; the engineering mind is
often frustrated by solely abstract ideas. However, you should have some
feel now for how finite fields can be constructed and how their members can
be manipulated. In particular, you will have seen that, apart from 0, elements
can be viewed either as logs (an expression of the power of 0.), or binary bit
patterns. It turns out that both representations are essential - for example,
you can't readily add elements if they're expressed as logs, multiplication
and division are much more readily achieved with logs.
Some problems, such as finding the roots of a polynomial, exist in both
domains at once and a solution to this will be examined later. Unfortunately,
movement between these forms is generally either fast and inelegant, via
look-up-tables, or slower but more compact, via algorithms. GF(2 2),
however, has logs which are offset from bit patterns by 1, i.e. a.i = i + 1,
making translation simple. Unfortunately, it's also rather a small field for
practical use.
Chapter 3

ERROR DETECTION

Techniques for error detection and error correction are often, although not
always, related. All work on the idea of creating space between valid coded
messages. With error correction, however, more space is generally required
as is some mechanism for finding the nearest valid message to a corrupted
one. Error detection provides a gentle introduction into practical coding and
two techniques are examined. Both techniques can be applied to error
correction and provide the ideal starting point.

3.1 The Horizontal and Vertical Parity Check

Almost without a doubt, you will have heard of or used parity as a means
of checking for errors. The parity bit is an extra bit added to a data word to
fix its weight (the number of set bits) in a known state of either even or odd.
It was shown in the introduction how this creates a minimum Hamming
distance (dmin) of two bits in between valid messages by doubling the total
message space. This technique has been employed in many low-speed serial
communications links for decades. Some examp1es of parity are shown in
Table 3.1 below. Column E contains the even parity bits whi1e column 0
shows the odd parity bits.

A. Houghton, Error Coding for Engineers


© Kluwer Academic Publishers 2001
26 3.1 The Horizontal and Vertical Parity Check

Table 3.1 Examples of horizontal parity

Data E 0

0 0 1 0 1 1 0 1 0 1
1 1 1 0 1 1 1 1 1 0
1 1 0 0 1 0 0 0 1 0
1 1 1 0 0 0 1 0 0 1
0 0 0 0 0 0 1 1 0 1

Because dmin is 2, no even bit errors (multiples of two bits) within a single
character will be detected. The first error moves the message into the invalid
space in-between valid messages, whi1e the second error moves the message
back into the valid message space. This is unfortunate since burst errors,
typically created by spikes on power supplies, often comprise a few correct
bits in between two error bits. The last row in Table 3.1 contains a five-bit
burst error, where the third and seventh bits are in error. At the receiver
these errors will pass undetected. This effect can be partly offset by
including a vertical parity check (often called achecksum) with a block of
characters. This is not always practical since communication systems that
use parity are often asynchronous, making compilation of characters into a
block impossible as there may be arbitrary gaps between characters.
Choosing even parity, Table 3.2 shows the previous data with the addition of
such a vertical (even) parity check.

Table 3.2 Examples ofvertical parity

Data E

0 0 1 0 1 1 0 1 0
1 1 1 0 1 1 1 1 1
1 1 0 0 1 0 0 0 1
1 1 1 0 0 0 1 0 0
0 0 !! 0 0 0 1 1 0

1 1 !! 0 1 0 !! 1 ~Received parity
1 1 1 0 1 0 ! 1 ~Expected parity
CHAPTER 3. ERROR DETECTION 27

In this case a difference between the received and expected vertical parity
alerts the receiver to the presence of errors not detected by the horizontal
parity checks. Even so, strategically positioned multiples of four error bits
can still go unnoticed by both horizontal and vertical checks. Some systems
calculate the vertical check by adding value of each character and discarding
the higher order bits of the sumo This technique can help to offset systematic
errors where, for example, the bit patterns in certain characters may
predispose them to corruption.
If you've studied communications or digital signal processing, you may
weIl be aware of schemes like eight to fourteen modulation (EFM) wh ich
seek to impose desirable frequency characteristics onto the aIlowed
(modulated) codes, making them suited to the channel through wh ich they
must pass. With raw data, where long (or short) runs of ones or zeros are free
to occur, this is not possible. Interactions between the channel and the codes
can, therefore, give rise to repeatble errors wh ich may weIl cancel each other
if only simple vertical parity is used.

3.2 The Cyc1ic Redundancy Check

Basic horizontal parity incurs an overhead of about 11 % of the channel


bandwidth. GeneraIly it is used in applications where this does not matter but
in high performance systems its poor ability to detect errors, coupled with its
high redundancy, render it unfavourable. Where performance is necessary, a
better choice of error detection is found in the cyclic redundancy check or
CRC. The CRC is referred to as a block code, because it is calculated over a
block of data. Consider an rn-bit message arranged as dm- I to do, where dm- I is
sent first and the last n bits of the message are set to zero, to be replaced
subsequently by the CRC during transmission. The CRC is calculated over a
finite field GF(2 n ) using a GP of degree n + 1 as in (3.1)

m-I
CRC= Ld;CX; (3.1)
i=n

where d; is 0 or 1. While it' s probably not obvious from this deceptively


simple equation, by adding the CRC to the message in bit positions dn- I to do,
we're making the message exact1y divisible by the GP. The CRC represents
the remainder accrued when the message (plus zeros) is divided by the GP.
So when the message plus CRC is subsequently divided by the GP, the
28 3.3 Longhand Calculation of the CRC

remainder will be zero. It' s a bit like taking a number, for example 14,
dividing it by another number, say 5, and transmitting 10 (14 minus the
remainder). At the receiver the received message should be divisible by 5.
Once the CRC is appended to the message, replacing dn_ 1 to do, (3.2) is true

rn-I
Ldia/ =0 (3.2)
i=O

3.3 Longhand Ca1culation of the CRC

Consider the message 10110110. Suppose we want to add a 4-bit CRC to


this, the first step is to add four zeros to the end of the message giving

10 11 01100000
from (3.1), this becomes

To generate a 4-bit CRC, it is necessary to operate over a 4-bit field GF(24)


which requires a 5-bit GP. One such GP is x4 + ~ + 1 = O. Using the
equivalence of:i to a i , we could change the calculation to

Xli + 0 + x9 + i + 0 + x 6 + x5 + 0 + 0 + 0 + 0 + 0

and then, using the GP, move the bits rightwards into positions x3 to xo. This
is most easily accomplished using a long division, as follows in Table 3.1.
Using x4 + i + 1, generate the field and try adding the elements a ll , a9, a 8,
a 6 and a 5 to verify the result. The steps involved in calculating the CRC are
as folIows:

1. append as many zeros to the data as there will be CRC bits (one fewer than
GP)
2. line up the MSB of the GP (underlined) with the first 1 (italic) in the data
andXOR ($)
3. line up the MSB of the GP with the next 1 (italic), bring down data bits
and zeros (.J,) as needed
4. XOR and go back to step 3 until there are no bits greater than x 3•
5. the remainder under the appended zeros (bold) is the CRC.
CHAPTER 3. ERROR DETECTION 29

Table 3.1 Longhand calculation ofthe CRC

1 1 0 1 0 0 1 0
1 0 1 1 0 1 1 0 0 0 0 0
1 1 0 0 1 J,
EB 1 1 1 1 1
1 1 0 0 1 J, J,
EB 1 1 0 1 0
1 1 0 0 1 J, J, J,
EB 1 1 0 0 0
1 1 0 0 1 J,
EB R 0 0 1 0

The transmitted message is 10 110 11000 10, comprising eight data and four
check bits. The quotient is discarded serving only as arecord of where the
eXORing took place. At the receiver an almost identical process takes place.
The only difference is that the CRC is used in the division rather than
appending four zeros. This is shown in Table 3.2.

Table 3.2 Checking for errors at the receiver

1 1 0 1 0 0 1 0
1 0 1 1 0 1 1 0 0 0 1 0
1 1 0 0 1 J,
EB 1 1 1 1 1
1 1 0 0 1 J, J,
EB 1 1 0 1 0
1 1 0 0 1 J, J, J,
EB 1 1 0 0 1
1 1 0 0 1 J,
EB R 0 0 0 0

In the absence of errors the remainder is zero, but if a detectable error has
occurred, then it will be non-zero. This result can be verified by adding the
elements a ll + a 9 + a 8 + (i + a 5 + a (from 3.2), based on the Is in the
message. This result is shown in Table 3.3.
30 3.3 Longhand Calculation of the CRC

Table 3.3 Calculating the Remainder using (3.2)

a ll 1 1 0 1
a9 0 1 0 1
a8 1 1 1 0
a6 1 1 1 1
a5 1 0 1 1
al 0 0 1 0
L 0 0 0 0

Table 3.4 gives a reworking of the remainder with two added bit-errors
(bold).

Table 3.4 Decoding a message with errors

Q 1 1 1 0 0 0 0 0
1 0 0 1 1 1 1 0 0 0 1 0
1 1 0 0 1 J,
EB 1 0 1 0 1
1 1 0 0 1 J,
$ 1 1 0 0 1
1 1 0 0 1 J, J, J, J, J,
Et> R 0 0 0 1 0

In this case, the remainder is 0010, or non-zero. In fact, the remainder is


equal to a 9 + a 7 , for this field, since the errors are in positions x9 and x7 • This
can be verified by using the GP to bring x9 + x7 back into the field as follows
in Table 3.5.

Table 3.5 Examining the Error Pattern

1 1 0 0 1 0
1 0 1 0 0 0 0 0 0 0
1 1 0 0 1 J,
EB 1 1 0 1 0
1 1 0 0 1 J, J, J,
EB 1 1 0 0 0
1 1 0 0 1 J,
EB R 0 0 1 0
CHAPTER 3. ERROR DETECTION 31

There are, however, error patterns which will not be detected. These can be
generated by adding the GP to the message in any arbitrary position. Table
3.6 gives an example of this. The errors are shown in bold, coinciding with
bits X 2(X4 + x 3 + 1).

Table 3.6 Non-detection of certain error patterns

1 1 0 1 0 0 1 0
1 0 1 1 0 0 0 0 0 1 1 0
1 1 0 0 1 t
1 1 1 1 0
1 1 0 0 1 t t
1 1 1 0 0
1 1 0 0 1 t t
1 0 1 0 1
1 1 0 0 1 t
1 1 0 0 1
1 1 0 0 1 t
0 0 0 0

Adding errors equal to the GP effectively creates another valid data + CRC
pattern. Using the field described by x4 + x 3 + 1, try adding any three
elements with the relationship a:~+i + a?+i + cl The GP changes a message
fromone valid code to another. Pragmatically, in these examples I have used
eight-bit data which means that there are 256 valid data bit patterns. Since
the CRC is only four bits, it can only have 16 different values. The 256 data
values must, therefore, map onto only 16 possible CRCs which in turn means
that 16 data patterns will share the same CRC. The corollary to this that 1 in
16 errors will go undetected. This may seem a disappointing result until you
consider that in reality the CRC will usually be 16 bits long, missing only 1
in 65 536 of all errors. Also, many burst errors will be smaller in length than
the GP which guarantees detection (can you think why?)

3.4 Performance

Performance can be measured in a variety of ways including detection


ability, bandwidth requirements and complexity. In a typical application a
16-bit CRC may be used to protect up to, say, 2 kbits of data. In terms of
bandwidth, this means that 1 bit in 129 is used for error checking compared
32 3.5 Hardware Implementation

with 1 bit in 9 for simple parity, or 0.78% of the channel instead of 11.1 %.
As far as detection ability goes, we can guarantee that all burst errors smaller
in length than the GP will be detected if the GP is primitive, and 2n -1 out of
2n errors in total where there are m bits in the CRC. For a 16-bit CRC this
works out to 99.9985% of errors. This calculation comes from the rash
assumption that a random error gives rise to a random result in the
remainder. If the remainder is n bits then 1 in 2n random results will be zero
and so not detected.
If the message size (data plus CRC) is less than 2n bits and the CRC is n
bits, then a single-bit error at Xi can be corrected since such an error produces
a unique remainder (Xi. For messages equal or greater than 2n bits, remainders
may be shared. In its simplest form, adding a CRC creates a dmin of 3 in
messages up to 2n - 1 bits. This might be increased, however, if the message
size is considerably less than this.

3.5 Hardware Implementation

Hardware implementation is mostly straightforward since all operations are


eXclusive ORing. There are as many edge-triggered registers as there are bits
in the CRC, one fewer XOR gates (2 input) as there are 'l's in the GP, and a
single AND gate. To construct the CRC generator, line up the GP, MSB to
the left so that the bits fall in between the registers, and connect as shown in
Figure 3.1. Where there is a '0' in the GP each Q output connects directly to
the adjacent D input. If there is a '1' in the GP, connection is via an XOR
gate, taking the second input to the XOR gate from a feedback path.

1 o o 1

I----~Q B D'/-----IQ A
ck ck

CRC out Data dock


Figure 3.1 Hardware CRC calculatar.
CHAPTER 3. ERROR DETECTION 33

Initially, with the switch in calculate mode, the registers are reset to zero
and the data are c10cked serially into the circuit. When the final data bit has
been c10cked in (no zeros added), the CRC is actually in the registers. To
c10ck it out without corrupting it, the switch is set to read out which disables
the feedback path. Three further c10cks serially output the CRC.
To verify the operation of the circuit we can use the data from the previous
example, both before and after corruption by errors. Table 3.7 shows the
initial calculation of the CRC. After all the data have been c10cked in, the
CRC resides in the four registers.

Table 3.7 Calculation ofthe CRC by hardware

A =FB' B=A' C=B' D = C' &FB' DATA FB =DATA &D

0 0 0 0 1 1
1 0 0 1 0 1
1 1 0 1 1 0
0 1 1 0 1 1
1 0 1 0 0 0
0 1 0 1 1 0
0 0 1 0 1 1
0 0 0 0 0

The last bit of data is c10cked in at this point and the AND gate switch is
OPENED (=0) to prevent the feedback from destroying the CRC now in
ABCD. The CRC c10cks serially out of the registers MSB First.

o 1 o o 0(0) 0(0)
o o 1 o 0(0) 0(0)
o o o 1 0(1) 1 (0)
o o o o 0(0) 0(0)

Table 3.7 also shows, in brackets, the situation at the receiver where the
CRC is appended to the data stream. In the absence of errors this results in
four zeros. Table 3.8 repeats the example in Table 3.4, where two errors have
been added. Again, the hardware result agrees with the longhand calculations
given previously. The circuit mirrors very c1osely, the form of the longhand
calculations, given above. The principal difference is that, by hand, we are
free to skip passed leading zeros in the numerator. In the circuit, Os appear in
the feedback path where they have no effect other than to shift the register
contents left, unchanged. When a one appears in the feedback, the register
contents are both shifted and modified by the form of the GP.
34 3.5 Hardware Implementation

Table 3.8 Calculation of the remainder with errors

A=FB' B=A' C=B' D = C' tf7FB' DATA FB = DATA tf7 D

0 0 0 0 1
1 0 0 1 0 1
1 1 0 1 0 1
1 1 1 1 1 0
0 1 1 1 1 0
0 0 1 1 1 0
0 0 0 1 1 0
0 0 0 0 0 0

0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 1 1
0 0 0 0 0 0

Appendix A gives a list of primitive polynomials that may be useful for


those wishing to experiment further. Standard polynomials for CRC
generation include

X I6 + X I2 + x 5 + 1 (or 1 0001 00000010 OOOb and 69665 10)


and
X I6 + x I5 + x 2 + 1 (or 11000000000000101 2 and 98309 10)

for 16 bits, and

for 12 bits.

These generator polynomials are not primitive, each having the factor
(x + 1), for example
CHAPTER 3. ERROR DETECTION 35

By multiplying a pnmitIve polynomial by (x + 1), the CRC length is


increased by 1, but the size of the field remains the same. We have seen that
the polynomial x 3 + x + 1 = 0 gives rise to a repeating sequence (Table 2.1)
of seven non-zero elements. Multiplying this polynomial by (x + 1) gives
x4 + i + x 2 + 1 = O. The element lengths and CRC are one bit longer but the
cycle is still only seven elements long. Starting with a = x, the cycle for this
polynomial is given in Table 3.9.
These are called expurgated cyclic codes and if we trade one of our data
bits for the extra CRC bit so that, say, a seven-bit message with four data bits
as could be generated by x 3 + X + 1 = 0 becomes a seven-bit message with
only three data bits, then the minimum Hamming distance (dmin ) between
valid codes is increased by one. The implications of this will be seen more
clearly when we consider cyclic codes as a means of error correction.

Table 3.9 Seven-element sequence using x 4 + y( + :l + 1 =0

Power Binary value

a 0010
a2 0100
a3 1000
a4 1101
a5 0111
a6 1110
a7 0001

3.6 Table-Based Ca1culation of the CRC

Often it is necessary to calculate a CRC within a micro-controller. While


bit-wise generation of the CRC is very economic, requiring only one word of
register space, it is also rather slow. It is possible to speed up the calculation
by using pre-calculated tables where table size can be traded for speed.
Typically tables will be byte or nibble oriented, the latter providing a good
speed/size trade off. This process works in the following way. Suppose the
message is eight bits and we want a 16-bit CRC using X 16 + X 12 + x 5 + 1. With
an 8-bit message, there will be 256 possible CRCs based on the possible
combinations of a 16 to a23 which we could store in a 256 location by 16-bit
look-up-table.
36 3.6 Table-Based Calculation of the CRC

8-bit message 16-bit CRC

Typically, messages will be more than 8 bits, so the CRC generator/look-


up-table is configured as follows, in Figure 3.2, below.

Figure 3.2 Calculating a CRC Using a Look-Up-Table.

To add a byte to the CRC, the CRC register is shifted left by eight bits,
shifting the new data byte into the lower eight bits of the CRC register. The
eight bits which are shifted out from the top of the CRC register access the
look-up-table and are converted back into finite field. The 16-bit output from
the look-up-table is XORed with the CRC register to form the new CRC.
This operation need not be 8-bit oriented. For a micro-controller solution, a
4-bit approach forms a good speed/resource compromise. In this case, a
16x16-bit (32-byte) look-up-table is required and the addition of a byte to the
CRC requires two 4-bit phases. CRC register is shifted left by four bits,
adding the high nibble of the new byte into the lower four bits of the CRC
register. The four bits which fall out of the top of the CRC register access the
look-up-table and the look-up-table output is XORed with the CRC register.
The operation is repeated, this time bringing in the lower four (remaining)
bits of the new byte.

LUT CRC data in

Figure 3.3 Nibble-Oriented Calculating a CRC Using a Look-Up-Table.

As an illustration, consider adding a 4-bit CRC to a data stream using the


GP x4 + X + 1 = O. Table 3.10 shows how the look-up-table is constructed
using the values a 4 = 0011, a 5 = 0110, a 6 = 1100 and a 7 = 1011.
CHAPTER3. ERROR DETECTION 37

Table 3.10 Calculation ofthe Look-Up-Table

Table Input Calculation Table Output

A3 A2 Al Ao Q3 Q2 Ql Qo
(x7 ) (x6 ) (x5) (x4 )
0 0 0 0 0 0 0 0 0
0 0 0 1 cl 0 0 1 1
0 0 1 0 a5 0 1 1 0
0 0 1 1 a 5+a4 0 1 0 1
0 1 0 0 a6 1 1 0 0
0 1 0 1 a 6+a4 1 1 1 1
0 1 1 0 a 6+a5 1 0 1 0
0 1 1 1 a 6+a5+a4 1 0 0 1
1 0 0 0 a7 1 0 1 1
1 0 0 1 a 7+a4 1 0 0 0
1 0 1 0 a7+a5 1 1 0 1
1 0 1 1 a 7+a5+a4 1 1 1 0
1 1 0 0 a 7+a6 0 1 1 1
1 1 0 1 a 7+a6+a4 0 1 0 0
1 1 1 0 a 7+a6+a5 0 0 0 1
1 1 1 1 a 7+a6+a5+a4 0 0 1 0

Consider the message 10001100111. First, this must be split up into nibbles,
and four zeros appended, giving 0100 0110 0111 0000, or 4 6 7 O. The CRC
register is cleared to 0 and 4 is presented to the input.

[LUT
.~4Input
1 0 ~ o CRC

The XOR output will be 4 since the look-up-table (LUT) will output O. Now,
6 is presented to the circuit input and 4 is presented to the LUT .

[ LUT • ~6Input
I OC I'" 4 CRC
38 3.6 Table-Based Calculation of the CRC

The LUT output will be OC, so the XOR will output OA to the CRC register.
Now,7 is presented to the circuit input giving

LI L~~ w~--~
~~7
CRC Input

with OA on the XOR output, again. Finally, the appended 0 is input to the
circuit

L LUT
I OD ~~--
~~:t:
OA CRC
0
Input

which, after clocking leaves

LI LUT
4
~~~put
WI"'--~ CRC
Now, the CRC register holds the final result, OD or 1101. We can compare
this with a long-hand calculation of the CRC as folIows, which agrees.

10000111011
1 0 0 0 1 1 0 0 1 1 1 0 0 0 0
1 0 0 1 1 J, J, J,
1 0 1 0 0
1 0 0 1 1 J, J,
1 1 1 1 1
1 0 0 1 1 J,
1 1 0 0 1
1 0 0 1 1 J,
1 0 1 0 0
1 0 0 1 1 J, J,
1 1 1 0 0
1 0 0 1 1 J,
1 1 1 1 0
1 0 0 1 1
1 1 0 1
CHAPTER 3. ERROR DETECTION 39

3.7 Discussion

Where data are to be organized into blocks you will see that the CRC
provides a greatly enhanced error detection capability over simple parity
checking and at a greatly reduced cost in terms of bandwidth. A 16-bit CRC
appended to a typical message of, say, 2 Kbits uses about 0.8% of the
channel as opposed to around 11 % for parity. For infrequent and intermittent
communication, however, parity will be more applicable because bandwidth
is not usually an issue and compilation of data words into blocks is not
possible.
You should be able to ca1culate a CRC on a block of data given a suitable
generator polynomial, and derive a hardware generator from the polynomial
bit pattern. Also, for software solutions, you should be able to construct a
suitably sized look-up-table to speed up the CRC ca1culation.
The nature of the CRC ca1culation means that certain errors will not be
detected since the corrupted message is still exactly divisible by the GP.
When this happens, the message has moved through some multiple of dmin
bits into a new valid message.
Chapter 4

ERROR CORRECTION BY PARITY

We have already passed over rudimentary error correction in the form of


both parity checking and the cyclic redundancy check. Table 3.2 shows an
example of vertical parity checking in conjunction with horizontal parity
checking. The purpose of that particular example was to illustrate that some
of the shortcomings of the simple horizontal parity check could be overcome.
If, however, only a single-bit error occurs then the bit which is intersected by
both horizontal and vertical parity errors will be the bit in error, and it can be
corrected.
Rather than look at the very simple case of intersecting horizontal and
vertical parity checks as a mechanism for error correction, we'll consider the
slightly more general case of Hamming codes which are based on parity
checks. Hamming codes represent the first serious attempt at providing a
mechanism for error correction and they work by introducing a minimum
Hamming distance of 3 between valid codes. Hamming codes are perfect
codes which work by breaking a 2n - I-bit message into n dimensions and
,ca1culating a single parity bit for each dimension.
Consider a (7, 4) message comprising, d6 to d 3 and P2 to Po. Figure 4.1
shows the data bits arranged into three dimensions for this example. One
parity bit resides in each surface. The parity bits are arranged so that the
overall parity of each surface is known, even or odd. Notice that no parity bit
depends on any other. In principle this is exactly the same as the horizontal

A. Houghton, Error Coding for Engineers


© Kluwer Academic Publishers 2001
42

and vertical parity check except that the data are now arranged in higher
dimensional formats.

Figure 4.1 Calculating a (7, 4) code.

At the receiver the parity is recalculated based on the received codeword.


In the event of a single-bit error, the parity in one or more surface will be
incorrect. By noting which surfaces exhibit a parity error the erroneous bit
can be isolated. If, for example, the surfaces pertaining to Po and PI exhibit
parity errors, the only bit common exclusively to both surfaces is d s. This
must, therefore, be the bit in error. The parity equations for the arrangement
illustrated above are

ds +
ds

These in turn give rise to the codewords in Table 4.1 below. A careful
examination of the codewords will show that at least three bits must be
changed to get from one codeword to another codeword. The code, therefore,
satisfies the requirement that the minimum Hamming distance must be 2t + 1
between codes, and t is one for a single-bit error correction. A useful
property of the codewords is that they are linear. This means that they can be
combined (by eXORing), to produce other valid codewords. By storing only
the codewords for one, two, four and eight, all others can be constructed. For
example, taking the code for one (0001 111) and adding to it the code for
eight (1000 101) gives the code for nine (1001 010). Using Table 4.1 you can
try other combinations.to verify this.
Other documents randomly have
different content
ajoi seksmanni heidän ohitsensa, osaamatta mitään pahaa aavistaa,
varmana voitostaan, kuuliaiskestit mielessään. Nuoret, jotka seisoivat
vähän matkaa tieltä, näkivät hänen, hän onneksi ei heitä. — Ja
seuraavana päivänä kuulutettiin: nuori mies Lauri Laurinpoika
Kilmala ja nuori neiti Aini Vierre.»

*****

»Ja nyt tuli maisterin vastata työstään.

»Miten hän siinä suoriutui — mitä hänen ja seksmannin välillä


puhuttiin, kun he tuossa vesivärillä maalatussa kammarissa kahden
kesken olivat, sitä ei tietäne kukaan muu kuin asianomaiset. Arvelen
vaan, ettei nuori pappi juuri ihan huvikseen siellä ilmaissut, minkä
kepposen hän oli seksmannille tehnyt. Ja minä tiedän, että hän
silloin suuresti katui asiaan ryhtymistänsä.

»Me, seksmannin kuuliaisvieraat, joiden joukossa minäkin olin,


emme nähneet mitään kummaa siinä, että maisteri ja seksmanni
sulkeusivat kahden kesken kammariin, eikä aivan paljon siinäkään,
että Lauri ja Aini sinne käskettiin; mutta sitä suurempaa
kummastusta herätti meissä heidän katseensa, kun he kaikki neljä
sieltä astuivat tupaan. Ja siihen lisäksi oli jo Muona-Matti ja Karja-
Kaisa ehtineet antaa pieniä viittauksia… Seksmannin silmistä leimusi
tuli, joka pelästytti; siinä ei ollut enää tuota entistä jääkylmää
katsetta: siinä kuvastui — sen näki selvään — häädetty viha. —
Lienee maisteri asettanut ukon eteen kuvastimen ja siinä antanut
hänen nähdä oman itsensä oikeassa karvassaan; oli miten oli,
maisteri ei sillä voittanut muuta kuin että seksmanni näki parhaaksi
antaa asian jäädä semmoiseksi, jommoiseksi se oli muodostunut,
nostamatta siitä mitään melua. Kaiketi ymmärsi hän, ettei hän
käräjöimälläkään voittaisi muuta kuin ivaa ja häpeää, vaikka saisikin
maisterin edesvastaukseen.

»Ikävät olivat nämä kuuliaiskestit, ikävimmät kaikista, missä olen


ollut. Seksmanni ei puhunut sanaakaan päivällispöydässä, otti vaan
hopeamaljasta aimo kulauksia — hän, joka aina oli tyytynyt veteen
ja kaljaan — mutta ei tullut sen puheliaammaksi. Mitä hänessä
liikkui, se näkyi silmäyksistä, jotka hän silloin tällöin heitti maisteriin
ja kihlattuihin, ja vieläpä siitäkin, että hän, tuntematta kipua, pureksi
ohuet huulensa verille.

»Ei auttanut maisterin kaunis puhekaan, jossa hän muun muassa


muistutti kihlatuita siitä kunnioituksesta, jota he olivat velvolliset
osoittamaan seksmannille, ja jonka johdosta Lauri nuorempi vastasi,
että hän ja Aini aina tulisivat kohtelemaan isää niinkuin lasten tulee
kohdella vanhempiaan ja että he kykynsä mukaan koittaisivat tehdä
hänen vanhat päivänsä iloisiksi.

»Tämän päivän perästä ei seksmanni enää tullut entisellensä. Hän


pysyi enimmäkseen kammarissaan, eikä kärsinyt nähdäkään
poikaansa ja tämän morsianta. Häpesikö hän, katuiko hän vai
kaiveliko salainen, sammumaton viha hänen mieltään? Hän ei
ryhtynyt mihinkään, ei puhunut tuskin sanaakaan, ei komentanut
edes Karja-Kaisaa. Ja eräänä aamuna — nuorten toisena
kuuliaispäivänä — istui hän halvattuna kammarissaan. Kynttilä paloi
pöydällä ja sen vieressä oli suuri velkakirja- ja setelikasa, hiukan
palanut, mutta ei pilalle. Ukko oli tahtonut — polttaa ne kaikki. Mutta
mammonan orjaan lienee tämä tällainen kosto — jolla hän itse omat
epäjumalansa hävitti — koskenut liian kovasti. Kun hän vuoteelleen
kannettiin, oli hänen vasemmassa kädessään Vierteen talonkirjat, ja
kun niitä tahdottiin siitä ottaa, öyhki ukko ja ärisi. Hän oli kadottanut
puheenlahjan ja hänen ruumiinsa oikea puoli oli tunnoton.

»Tuossa tilassa eli hän viikon päivät. Karja-Kaisa ruokki ja hoiti


häntä niinkuin pientä lasta; muita hän ei sietänyt nähdä. Ja
kädessään piti hän kaiken aikaa Vierteen talonkirjoja. Jos ken koitti
niitä häneltä ottaa, silloin näkyi, että ukko eli.

»Tapana on, että kihlatut kolmantena kuuliaispyhänään ovat


kirkossa kuuntelemassa, kun heidän nimensä saarnatuolista
mainitaan. Lauri ja Aini eivät tätä tapaa noudattaneet. He olivat
olleet kovin suruissansa siitä tosin sanattomasta, mutta kumminkin
silminnähtävästä vastenmielisyydestä, vieläpä tuskastakin, jota
seksmanni osotti, kun hän heidät näki. Nyt olivat he luulleet
löytäneensä keinon, joka masentaisi ukon vihan. Aini kurkisteli
ovenraosta kammariin ja viittasi kiireesti Laurille. Seksmanni oli
muuttanut oikeaan käteensä Vierteen paperit. Oliko halvaus
antaunut?

»Lauri avasi oven ja laskeusi, Aini vieressään, polvilleen vuoteen


viereen, pyytäen että isä vihdoinkin leppyisi ja antaisi heille
siunauksensa. Vierteen, Kilmalan talot — kaikki olisi isän; Lauri ei
pyytänyt muuta kuin että isä laskisi kätensä heidän päälaelleen…

»Ja seksmanni ojensi kätensä — oikean. Ja Lauri ja Aini odottivat,


että tämä käsi heidän päälaelleen laskeutuisi. Turhaan odottivat he.
Kun he vihdoin loivat silmänsä seksmanniin, oli tämä — kuollut.
Mutta käsi oli auennut ja Vierteen paperit makasivat Ainin
helmassa…

»Lauri ja Aini ovat vielä sitä mieltä, että seksmanni siunasi heitä.
Ja hyvä on, että he niin luulevat. Minä olen vähän toista mieltä, sillä
minäkin tunsin Kilmalan seksmannin… Mutta tuossahan on
hirrenpää, josta saan suuteita hänen kaatumaisillaan olevan ristinsä
tueksi.»

Mörkö-Maija.

Hiljaa keinuttelee lämmin länsituuli Koskelan ruisvainiota, jonka


täyteläiset tähkät, maahan päin kallistuneina, rikasta satoa lupaavat;
hiljaisesta yölevostaan nousee talonväki ja valmistautuu leikkuuseen.

Aamu on kaunis. Taivas on sininen. Hiljaista, yksitoikkoista


lirinäänsä lirisee puro, johon vainio päättyy.

Niin, yhdeltä taholta rajoittaa vainiota tuo pieni, lirisevä puro,


toiselta, Koskelaa vastapäätä olevalta puolelta metsä, joka pieneksi
kukkulaksi kohoutuu ja jonka puitten välistä mahtava talo ja sen
tilukset — sen laajat tilukset — näkyvät.

Siinä, metsäisellä kukkulalla, istuu lahonnutta kantoa vastaan


nojautuneena vanha vaimo. Kuinka ryppyinen on hänen otsansa, ja
hänen poskensa — kuinka kurttuiset ja keltaiset! Juomuinen huivi,
joka hänellä on ollut päässään, on valunut alas hänen
ahavoittuneelle, tumman ruskealle niskalleen; hiljainen tuuli
pörröttelee hänen harvoja, lumenvärisiä hapsiaan. Hänen pienet,
harmaat silmänsä ovat käännetyt Koskelaa kohden, ja näistä silmistä
lentää salamoita. Ojennettu on hänen paljas, laiha käsivartensa,
jonka väri vetää vertoja lehmänsienelle, mikä kasvaa hänen
kurttuisen jalkansa vieressä. Ja hajallaan ovat käden sormet.
Äsken vielä seisoi hän kantonsa vieressä, ja silloin olivat hänen
molemmat käsivartensa ojennetut. Aamuruskon koittaessa laskeusi
hiljaa vasempi. Kun auringon terä alkoi näkyä, vaipui vanhus
istumaan, mutta oikea käsi ei ojennettua asemaansa muuttanut.

Hän istuu siinä sitten kauan liikkumattomana. Hän on miltei alasti.


Ei verhoa hänen ruumistansa muu kuin repaleinen, sammalen
värinen paita ja lyhyt punertava hame. Hän on kauhean näköinen.

Hänen huulensa liikkuvat, mutta sanaa hänen suustaan ei ole


hiljainen aamu kuullut.

Hänen silmänsä eivät räpähdä. Hän katsoa tuijottaa yhä Koskelaa


kohden.

Vihdoin viimeinkin huomaa hän, että talon väki on herännyt; ja


kun hän sen huomaa, vetäytyvät hänen keltaiset, ryppyiset kasvonsa
kokoon, ja hänen silmistään lentää säkeniä, jotka näyttävät tahtovan
sytyttää tuleen koko talon. Yhä nopeammasti liikkuvat hänen
huulensa, ja hänen ojennettu kätensä vapisee.

Jo kuulee hän, että talon väki on liikkeellä, ja hän nousee. Hän


ojentaa nyt vasemmankin käsivartensa taloa kohden, ja hajallaan
ovat vasemmankin käden sormet.

Jo näkee hän talon emännän astuvan ulos huoneesta; ja kun hän


sen näkee, oikoo hän ruumistaan. Hän nostaa kolmasti kätensä
taivasta kohden, ja kolmasti laskee hän ne alas. Sitten huutaa hän
täyttä kurkkuaan kolme kertaa peräksyttäin:

»Kirottu … kirottu … kirottu…!»


Ääni on kimakka, mutta ei se kauas kuulu; heikot ovat vanhuksen
voimat.

Kun sen viimeinen värähdys on kajahtanut, laskeuvat jälleen


hänen kätensä; huulet avautuvat nauruun, kamalaan nauruun, ja
hän kääntyy kiireesti. Oikea käsi tarttuu kannon nojassa seisovaan
sauvaan, vasempi pieneen, maassa makaavaan myttyyn. Ja eukko
katoaa hiljaa kulkien metsään. — Kuka on hän? Mitä tietävät hänen
kamala käytöksensä ja hänen kauheat sanansa? — Koskelan emäntä
on äkkiä seisahtunut. Kuuliko hän kirouksen? Mahdotonta! Kukkula
on siksi kaukana ja sen lisäksi tuuli vastainen. Mutta kumminkin
seisahtuu hän.

»Mikä se?» kysyi hän itseltään. »Kuinka nyt juolahti mieleeni


Mörkö-Maijan eilinen uhkaus: 'Muistat minua huomenna!'… Niin,
jopa muistan… Mutta mitä tarkoitti hän tuolla lisäyksellään: 'ja joka
päivällä on huomisensa, aina viimeiseen asti?'»

*****

Hiljaa keinuttelee lämmin länsituuli Koskelan suurta ruisvainiota,


jonka täyteläiset tähkät, maahan päin kallistuneina, rikasta satoa
lupaavat. Vainio odottaa leikkaajaansa.

Ja leikkuuväkeä kokoontuu Koskelan tupaan, miehiä ja naisia. He


eivät ole iloisen näköisiä. He asettuvat kukin pöytään, joka on
laihalla ruoalla katettu.

Pienessä vuoteessaan herää Liili, Koskelan isäntäväen ainoa lapsi,


sinisilmäinen, punaposkinen, iloinen, isän ihastus, äidin kaikki.
Hänen heleä naurunsa soi. Lapsen ilo on tarttuva. Leikkuumiesten
nurpeat kasvot kadottavat nurpeutensa; hymy asettuu heidän
huulilleen.

Koskelan isäntäväki on saitaa, ja siitä se on tullut pahaan


maineeseen. Palkolliset eivät siellä tahdo viihtyä: palkka on huono,
ruoka vielä huonompi. Mutta sen sijaan vaaditaan heiltä paljon.
Karsain silmin katsoo varsinkin emäntä heidän päivällisuntaan;
ennen aikojaan häiritsee hän sitä. »Isännän kanssa tulisi toki
toimeen», sanovat palkolliset; »mutta emäntä… Vaivainen hänen
kynsiinsä joutuu!»

Tänään, kun leikkuu on aljettava, on työväki luullut saavansa suun


avajaiseksi kahvia. Vaarasen Kaisa tietää, että viime vuonna sitä
annettiin. Mutta nyt, kun väki tupaan tulee, ei tultakaan ole takassa.

Kylmää ruokaa: leipää, silakoita pöydällä.

»Ei minua monta päivää täällä nähdä», sanoo tovereilleen Lassi,


vanha loismies, joka ei tiedä kahvia parempaa.

»Ennen muinen sitä ryypyllä aljettiin», mumisee Tahvana, vanha


loismies hänkin, jonka pääherkkua väkijuoma on.

»Saas nähdä, annetaanko puuroon silmääkään!» utelee Kaisa-


Liisa, joka koko leikkuu-ajaksi on taloon pestattu.

»Ei vallesmannissakaan tällaista kurjuutta», valittaa Silmäpuoli-


Mikko, ja sitten lisää hän: »vaikkei sielläkään kaksista; parempaa toki
kuin täällä. Tulevalla viikolla siirryn sinne.»

Niin murisee työväki. Kukin saa vapaasti purkaa sydämensä.


Isäntä on ulkona pellolla, emäntä on mennyt aittaan.
Silloin herää Liili.

Hän, pieni kolmivuotinen tyttö, on kaikkien lemmikki. Häneen


kääntyvät kaikkien silmät. Hän hosuu ympärilleen. Kärpäsiä
puhuttelee hän pikkulintusiksi; hän tavottelee niitä pienillä käsillään.
Sitten kurottaa hän kätensä leikkuuväkeä kohti, mutta kätkee ne
kiireesti peitteen alle, kun joku tahtoo niihin tarttua. Hän nauraa
ääneensä: »Piilosilla, piilosilla!» Hän vetää peitteen päänsä päälle:
»Sokkosilla, sokkosilla!»

Leikkuuväki katselee häntä mielihyvillään. Se ei muista äskeistä


kiukkuansa; se kuuntelee pienosen pakinaa ja hymyilee hänen
kujeilleen. Nurina on hälvennyt.

Yhä uutta väkeä astuu tupaan.

Silloin samoo emäntä sisään. Hän on kalpea vihasta; tyhjä


kaljatuoppi on hänellä kädessään. Hän tulee kellarista. Joku on siellä
käynyt. Kaljatynnyrin tappi on poissa; tynnyri on tyhjä, ja lattialla —
mikä siivo! Kuka on ilkityön tehnyt?

Kysyä saa; mutta eipä tekiä ole tynnyriin puumerkkiään piirtänyt.


Emännällä on kellarin avain. Ei sinne pääse muut kuin hän; lienee
hän itse illalla höllästi pannut tapin kiinni!

Ei, sitä hän ei ollut tehnyt. Hän oli sen lujaan painanut. Hän on
itse varma siitä… »Ah, Mörkö-Maija!»

Mutta miten hän oli kellariin päässyt? Lukossahan oli ovi, ja avain
emännän avainkimpussa. »Ah, noidan vehkeitä!»

»Onko Maijaa nykyjään näillä seuduin nähty?» kysyi Vääräsuu-


Jussi.
»Kävihän se retkale täällä eilen; pyysi leipää, pyysi jauhoja,
perunoita ja voitakin, mutta minä hänelle passin annoin.» Ja emäntä
viittasi ovea.

»Kyllä ei Maijan kanssa ole hyvä leikkiä laskea», tuumaili Jussi.


»Mutta olen kuullut, ettei hän kosta omasta puolestaan… Oliko hän
yksin?»

»Mitä se sinuun koskee? Ihan yksin hän oli.»

»Oli kyllä, se on tosi», tokasi siihen Kaisa-Liisa, sama, joka koko


leikkuu-ajaksi oli Koskelaan pestattu; »mutta tuskinpa olitte ajanut
hänet tuvasta, niin tulihan Hölöpän-Matin Miina sisään pienen
raajarikkoisen tyttärensä kanssa ja pyysi Jumalan tähden illallista,
muistattehan, emäntä!»

»Ole vaiti! Jos minä kaikkia Miinoja ja kakaroita syöttäisin…»

»Ja sitten — kuulittehan sen — uhkasi Mörkö-Maija teitä, — puhui


jotakin huomisesta. Ja kohta sen jälkeen menitte te kellariin.»

»Niinhän tein», myönsi emäntä ja kävi hiukan ajattelevaksi. Hänen


mieleensä johtuivat taasen Maijan sanat: »muistat minua huomenna,
ja jokapäivällä on huomisensa, aina viimeiseen asti…» Olisiko
Maija?… Hyvin mahdollista. Hän on tietäjä, suurikin tietäjä;
kaukaahan ihmisiä hänen luonaan käy. Viime talvenakin — niin
ainakin puhuttiin — pakoitti hän varkaan viemään takaisin Suurpään
Kallen kellon…

Emännän ajatuksenjuoksua keskeytti äkkiä ääni:

»Äiti!»
»Kah, joko sinäkin olet herännyt, Liili?»

»En, äiti, minä vielä nukun, minä näen unta.»

»Vai niin; mitä unta sinä näet?»

»Tuo ruma akka on täällä, mutta hän ei tee minulle pahaa… Hän
taputteli poskiani ja sanoi: 'se oli oikein, että tahdoit antaa voileipäsi
tuolle pienelle tytölle'… Äiti, miksi en saanut antaa?»

»Kuka ruma akka, kuka pieni tyttö? Kenestä sinä puhut, lapseni?»

»En tiedä, äiti… Hän sanoi myös, että minä olen hyvä tyttö ja että
sinä olet paha. Mutta minä sanoin, että sinä olet niin hyvä, niin hyvä
— Liilille.»

»Lapsi on nähnyt unta Mörkö-Maijasta ja Hölöpän-Matin Miinan


tytöstä», kuiskasi Kaisa-Liisa puoliääneen. Emäntä sen kyllä kuuli,
mutta hän ei ollut sitä kuulevinaan. Lapsen sanat olivat tehneet
syvän vaikutuksen häneen. Liili oli jo nukkunut, kun Mörkö-Maija ja
Matin-Miina Koskelassa kävivät; eihän hän voinut niiden käynnistä
mitään tietää. — —

»Voi, voi sentään!»

Kaikkien silmät kääntyivät oveen päin.

Siitä ryntäsi sisään Karja-Lotta, silmät selällään. »Halki se on, ihan


halki: voi, voi sentään!»

»Mikä on halki? Oletko tullut hulluksi?» huudahti emäntä.

»Pata on halki, muuripata, tiedänmä! Vesi juoksee pesään…


Menen tekemään haudetta Mansikille, joka on sairas ja ähkää;
menen kotaan, vinttaan vettä pataan, rupeen laittamaan tulta… No,
ei tässä maailmassa! Pesä on yhtenä järvenä, ja pata on tyhjä… Se
on halki, ihan halki, sanon ma; ei se pidä vettä, ei! Ja…»

»Onko muuripata halki — uusi muuripata?» keskeytti häntä


emäntä hämmästyneenä. »Kuka sen on halaissut? Sinä, tietysti, sen
mokoma! Mutta saatkin maksaa sen: viime markkinoiltahan Manne
padan osti.»

»Minäkö? Maksaa! E-ei, siitä nyt ei lähde mitään! Pata on halki, se


on varma, se…»

»Mutta minä sanon, että sinä maksat sen! Sinä jätit eilen tulta
pesään, etkä huomannut, että padassa oli vesi kiehunut kuiviin…»

»Vai niin, vai sekö sen padan halkaisi; sillä halki se on, siitä ei
pääse… Mutta, emäntä hyvä, kukahan kodassa eilen viimeksi kävi,
minäkö vai te? Vai ettekö tahdo muistaa?… Mörkö-Maija teitä vielä
pihalla manasi, ja Matin-Miina kuljetti pois ontuvan kakaransa… Te
pistäysitte humalistossa, hyppäsitte sitten kotaan ja sieltä kellariin…
Minä näin sen luhdin ovelta; olin juuri maata menossa… Ja kyllä sen
Mörkö-Maijakin näki… Niin sen asian laita on. Vai minäkö maksaisin
padan!… Se on nyt halki, siitä ei pääse! Ja… Voi, voi sentään! En
muistanut sitä sanoa: koko lammaslauma on kauramaassa… Kai
jätitte veräjän auki, kun humalistossa kävitte…»

Isännän tulo keskeytti Karja-Lotan sanatulvan. Koskela, kookas,


keski-ikäinen mies, oli käynyt ruisvainiolla katsomassa, mistä
parhaiten sopisi leikkuuta alottaa. Palatessaan oli hän nähnyt
lampaat kauramaassa, ja sisään astuessaan ärjäsi hän suuttuneena:
»Kuka roisto on humaliston veräjän auki jättänyt? Ennenkuin
leikkuulle lähdetään, ovat lampaat kauramaasta pois ajettavat. Joka
mies!»

Silmänräpäyksessä toteltiin isännän käskyä; eikä aikaakaan, niin


oli tupa tyhjä ihmisistä. Ei kumminkaan ihan tyhjä. Pikku Liili makasi
vielä pienessä vuoteessaan. Häntä ei ollut kukaan nyt muistanut, ei
äitikään, jonka täytyi kiiruhtaa katsomaan muuripataansa.

Ja Liili makasi siinä hetkisen rauhassa. Padan onnettomuudesta


hän ei ymmärtänyt mitään, mutta lampaat olivat hänelle tutut —
olihan hänellä niissä pieni oma karitsansakin. Hän ei oikein
käsittänyt, miksi niitä kauramaasta ajettaisiin: mutta ei hän sillä
päätänsä vaivannut. Hän katseli pieniä sormiansa, ja vasemman
kätensä sakarisormi oli hänestä hänen pikkukaritsansa, iso sormi
suuri sarvipää pässi, jota hän pelkäsi. Hän koetti matkia karitsan ja
pässin ääntä. Ja kun kärpäset lentelivät hänen vuoteensa ympärillä,
veti hän suunsa kurttuun: »Sys, sys, sanoo pikku lintu.» Sitten
rupesivat kädet piilosille. »Hae, hae!» Mutta viimein kyllästyi hän
leikkeihinsä. »Äiti, äiti!» huusi hän.

Mutta kun ei äitiä kuulunut, kömpi hän vihdoin vuoteeltaan, ja nyt


näki tuvan haltia, jos semmoista on olemassa, pienen, lihavan
tyttötassukan paitasillaan hyppivän lattialla. Se oli Liilistä niin
hauskaa. Hän marssi siinä »niinkuin isä;» hän pisti peukalon
suuhunsa ja oli tupakoivinaan; hän torui »niinkuin äiti Karja-Lottaa.»
Hän leikki nukkien kanssa ja asetti ne makaamaan vuoteeseen, josta
hän itse vasta oli noussut. Se oli niin hauskaa, niin hauskaa!

Mutta viimein kyllästyi hän ja rupesi lähemmin katselemaan


ympärilleen tuvassa. Siinä oli iso kasa sirppejä suuren kellokaapin
vieressä penkillä. Liili meni niiden luo. Ne olivat hänestä pieniä
viikatteita. Hän rupesi niitä käsittelemään; niistä sai hän uusia
leikkikaluja.

Sillä välin oli leikkuuväki saanut ajetuksi lampaat kauramaasta.


Isäntä, joka oli kulkenut vainion perukkaan saakka, ollaksensa
varma,
ettei ainoakaan eläin aitaukseen jäänyt, palasi sieltä viimeisenä.
Äkkiä seisahtui hän humaliston takana ja päästi kovan huudon:

»Tuokaa puukko tänne!»

Käskyn kuuli väki ja myöskin emäntä, joka oli kodassa käynyt ja


mieliharmikseen nähnyt uuden padan peräti tärvääntyneeksi sekä
päänpäätteeksi, aittaa tarkemmin katsellessaan, huomannut
valloilleen päässeen kaljan tunkeuneen suola-laariinkin.

»Mikäs on nyt taasen hätänä?» kysäsi hän, kun isännän käskyn


kuuli.

Humaliston takana oli pieni kumpu, ja siihen oli perunakuoppa


talven varalle kaivettu. Isäntä, kun kuopan ohitse oli kulkenut, oli
sattumalta luonut silmänsä siihen. Mikä se? Kuopan esiinpistävässä,
rattimaisessa ilmatorvessa oli jotakin outoa. Liikkuihan siinä lampaan
saparo. Niin oikein! Torveen oli takaa-ajossa yksi lampaista vajonnut;
hypyssään olivat sen molemmat etujalat aukkoon joutuneet. Eläin
parka oli taittanut niskansa. Ja niin lujasti oli se reikään tarttunut,
ettei isäntä saanut sitä siitä hinatuksi. Ällistyneenä seisoi hän siinä,
saparo kädessänsä. Sitten huomasi hän, että lampaassa vielä oli
vähän henkeä, ja hänen mieleensä juolahti, että se kohta olisi
pistettävä.

»Tämäpä päivä vasta onneton!» valitti emäntä, kun paikalle ehti.


»Jumalan kiitos!» kuiskasi Silmäpuoli-Mikko Kaisa-Liisalle: »nyt
saamme väkisinkin lampaan paistia. Nyt jään minä tänne vastaiseksi
enkä menekään vallesmannille vielä.» Ja kun sitten yhdistetyin
voimin lammas oli hinattu ahdingostaan ja se kummulla nurinniskoin
makasi, veti Mikko puukon tupestaan ja tarjosi sitä Karja-Lotalle,
joka Koskelassa teurastajan tointa hoiti. Mutta silloin siinä tapahtui
jotakin aivan odottamatonta.

»No, sen saan sanoa, olipa se koko tupsaus!» huusi Vääräsuu-


Jussi.

Kummulle oli kokoontunut enemmän väkeä kuin kuopan katto


kesti. Se romahti liiallisesta painosta sisään, ja siinä makasi nyt
kattopuiden, turpeiden ja mullan keskellä Koskelan isäntä, emäntä ja
leikkuuväki, allansa lammas, joka oli niskansa taittanut. Pölyä ja
tomua nousi, ettei siinä alussa mitään eroittanut. Kyllä se oli
naurettavaa, mutta kyllä ei kuopassa makaavien hauskaa ollut.
Kuinka he potkivat ja ponnistelivat! Karja-Lotta, joka oli kyyristynyt
lammasta kohden, kun romaus tapahtui, makasi siinä melkein
samassa asennossa kuin lammas äsken ilmatorvessa, ja hänen
päällään, multaa ja lautoja välillä, Silmäpuoli-Mikko, koivet suorana
ylöspäin; eikä kummallakaan nyt ollut mitään sanomista. Vaarasen
Kaisan päätä näkyi nenään asti, mutta suun kohdalla oli suuri
multamöhkäle, ja se nyt Kaisan kielen kurissa piti. Isäntä itse oli
jotenkin helpolla päässyt: hän istui hävityksen reunalla: jalat vaan
olivat mullistuksen peitossa. Emäntä ja Tahvana taasen seisoivat
sorassa kainaloita myöten, naamat niin likitysten, jotta melkein
koskettelivat toisiaan. Vääräsuu-Jussi ja Lois-Lassi eivät olleet vielä
kummulle ehtineet, ja siitäpä syystä he eivät yhteiseen pulaan
joutuneet.
Niin aivan; kyllä Vääräsuu-Jussi oli oikeassa, kun hän sanoi, että
se oli koko tupsaus, eikä Lassikaan ollut niin aivan väärässä, kun hän
tapauksen johdosta tuli miettineeksi, että vajoomiseen menee
tavallisesti paljoa vähemmän aikaa kuin ylöspyrkimiseen. He
ryhtyivät kumminkin molemmat, niin kiireesti kuin heidän oli
mahdollista, auttamaan tovereitaan.

Siinäkös mylläkkää, pölyä ja huutoa, ennenkuin kaikki taasen


seisoivat omilla jaloillaan! Isäntä kyllä pian saatiin hinatuksi aukon
reunalta, mutta eipä hänestä tänään näyttänyt olevan työnjohtajaksi
— yhtä vähän kuin leikkuuseen Silmäpuoli-Mikosta, joka sitten
saatiin korjuuseen. Isäntä liikkasi, näetsen, kovin pahasti, hän oli
kenties taittanut jalkansa; ja Mikko ukolta oli nenä mennyt aivan
väärään ylöspäin ja venynyt niin pitkäksi, että sen huippu silmää
kosketteli, ja sitä paitse oli hän pahasti satuttanut päänsä. Hän öhki
ja voihki ja tunnusteli jäseniään, kun tukevalla maalla taaskin seisoi,
ja oli aivan oikeassa, kun tuumaili, että kuopan katto oli ollut liian
heikko, tahi että puuainekset olivat olleet pilalle lahonneet. Sillä välin
tiuskui ja riiteli emäntä, että Tahvana oli asettunut häntä liian likelle
ja vaati, että hän korjaisi pois tupakille haisevan suunsa vähän
kauemmaksi, johon Tahvana nöyrästi vastasi, että hän aivan
mielellään sen tekisi, jos se vain kävisi päinsä. Vaarasen Kaisa
räpytteli ja mulkoili silmiään, kun ei mullalta saanut mitään
sanotuksi: epäilemättä pyysi hän tällä ainoalla mahdollisella tavalla,
että häntä autettaisiin; mutta Mikon mielestä oli Karja-Lotta ennen
muita saatava ylös, hän kun varmaan oli pahimmassa vaarassa, ja
samaa mieltä olivat Jussi ja Lassi. Mutta Lottaapa ei ollut niin helppo
auttaa. Hän oli saanut raskaimman kuorman kannettavakseen —
miltei koko katon — jotta ison aikaa kului, ennenkuin hän tuli
näkyviin. Jussi ja Lassi kaivoivat ja heittivät ylös kiviä ja lautoja,
minkä ennättivät, vaikkei tuo heiltä aivan kiireesti käynyt. He eivät
näyttäneet olevan millänsäkään emännän ja Tahvanan riidasta ja
avunhuudosta, eikä kentällä makaavan isännän kirouksista ja
voivotuksesta. Heittiväthän vain väliin heihin silmäyksen ja
lohduttavaisen: »kyllä, kyllä, odottakaa hiukkasen!» Tähän Mikko,
joka verta vuotavaa nenäänsä piteli ja väliin kosketteli
korvantaustaansa, mistä iso pala oli lähtenyt, vihdoin, juuri kun
Lotan jalat tulivat esille, pisti mietteensä: »kyllä; niin, kyllä on Lotta
roteva ja vahva, mutta saas nähdä, mitä hän tästä puuskasta
sanoo!» Ja sitten hän huudahti: »kas vaan!» kun Lotta
äkkiarvaamatta potkaista tokaisi Vääräsuu-Jussia vasten suuta, niin
että hampaat helisivät, »kas vaan, vielä on ämmä entisellään!»

Ja kyllä Lotta oli entisellään, kentiesi vielä entistänsä enemmänkin


entisellään. Kun hän viimein saatiin ylös, oli hän tosin vähän
typertyneen näköinen. Hän oli vähällä ollut tukehtua ahdingossaan;
lampaan villoja oli hänellä suussa, ja musta ja pölyinen oli hän kuin
nokikolari. Mutta pian hän siitä virkosi, varsinkin kun hän huomasi,
että hänen hameensa ja vielä paitansakin oli kappaleen matkaa
sivulta ja selän kohdalta aina alas asti halki — melkein liepeisiin
saakka — ja vielä pahemmasti halki kuin muuripata kodassa. Ja sepä
Karja-Lottaa harmitti. Ja Mikon syy se tietysti oli, sillä olihan Mikko
hänelle ojentanut puukkonsa juuri kun romaus tapahtui. Eukko
pudisti itseään niinkuin piehtaroinut hevonen, korjasi kouraansa
halenneen hameensa reunukset ja torui samalla täyttä suuta Mikkoa:
»sillä ei ole koskaan maailmassa kuultu, että kukaan paljastaa
puukkoa, juuri kun romaus tapahtuu!» Mikko koetti puolustaa
itseään. Hän sanoi, ettei kukaan ollut tietänyt romausta
aavistaakaan, eihän Lotta itsekään, ja että Lotan sopisi kiittää
Jumalaa, kun niin vähällä oli päässyt. »Sillä olisihan puukko voinut
pahempaakin jälkeä tehdä, kuin ratkoa vanhaa hamerepaletta.»
Sitten hän lopulta kysyi, mihin Lotta oli puukon pannut, vieläpä
näytti tahtovan ruveta likemmin tarkastamaan Lotan rikkinäistä
vaatetustakin, sieltä sen ehkä löytääksensä. Mutta silloinkos eukko
oikein suuttui, ja sen sai Mikko onnettomuudekseen niin
perinjuurisesti tietää, ettei sitä ikinä unohtanut. Kyllä hän joskus
ennenkin oli Lotan kouria kokenut, mutta nyt sai hän kipeälle
korvalleen aimo sutkauksen ja kuuli samalla jotakin revenneestä
nenästään mainittavan: ja se oli tyynen Mikon mielestä liikaa. Ärjyen
kivusta tempasi hän lautapalasen, sillä kuitatakseen saamansa
korvapuustin, ja aika tappelu olisi kaiketi siinä syntynyt, ja tiesi
kuinka kauan emäntä ja Tahvana vielä olisivat saaneet seisoa ja
katsella toisiaan suusta suuhun ja Vaarasen Kaisa harjoitelle silmiään
mulkoilemaan, jolleivät Lassi ja Jussi viimeinkin olisi raivostuneiden
väliin menneet ja saaneet heidän tulisimman vihansa ainakin vähäksi
aikaa asettumaan. Lotta oli torunut suulakensa kuiviin; häntä janotti
kovasti. Mikon korvallisesta juoksi verta, jota paitsi hänen nenäänsä,
joka oli suureksi pahkulaksi turvonnut, kovasti pakotti. Tiesihän sen,
että vettä he kaipasivat, Lotta ja Mikko. Molemmat palasivat sen
tähden kartanolle, Mikko pidellen nenäänsä ja Lotta hamettansa. Ja
vielä pihalta saakka kuului heidän toransa, vieläpä kaivon
kanneltakin.

Emäntä ja Tahvana olivat tällävälin ponnistelleet voimiansa ylös


päästäkseen. Siinä sattuivat heidän kasvonsa monta kertaa yhteen,
ja että tuo aina kovasti suututti emäntää, sen kyllä kuuli. Vihdoin sai
Tahvana jonkun verran multaa ja romua syrjäytetyksi, ja Jussin
avulla emäntä ja hän viimeinkin pääsivät pintehestään juuri parahiksi
nähdäksensä, miten Lassi hinasi ylös Vaarasen Kaisaa, joka valitti
olleensa aivan kuoleman kynsissä, kun multa oli estänyt häntä
hengittämästä suun kautta, ja nenäkin oli ollut melkein kokonaan
tukkeessa. »Koettakoonpas toinen, miltä se tuntuu!»
»Tupsaus» oli kumminkin päättynyt onnellisemmasti kuin olisi
voinut uskoa: »sillä olisivathan kaikki voineet taittaa niskansa,
samaten kuin lammas, joka hyvän esimerkin näytti» — sanoi
sittemmin Vääräsuu-Jussi. Mutta lukuunottamatta Silmäpuoli-Mikon
haavoja ja Karja-Lotan halaistuja vaatteita ei ollut kukaan muu
sanottavaa vahinkoa saanut kuin isäntä, joka ei kyennyt jaloilleen ja
joka varsin pahaa ääntä piti, kun Jussi ja Lassi hänet taloon
kantoivat ja hän sillä välin huomasi, että lampaat, jotka hetken aikaa
olivat takapihalla seisoneet, auki olevasta veräjästä olivat palanneet
takaisin vainioon.

Ei onnettomuus tule kello kaulassa, sanotaan, eikä yksi paha


toiselta tietä sulje. Olisi sopinut odottaa, että koskelaisten koetukset
tähän olisivat loppuneet, mutta — mitäpä vielä. Kun emäntä avasi
tuvan oven miehille, jotka isäntää kantoivat, oli siinä hänen edessään
näky. joka vähällä hänet kokonaan tyrmistytti. Pikku Liili istui
verisenä takan vieressä ja itki, ja pankolla istui Karja-Lotta paraikaa
käärien riepuja oikean jalkansa ympärille. Ja koko lattia oli miltei
yleensä veressä. — Karja-Lotta oli huoneeseen samotessaan astunut
sirppikasaan, minkä Liili oli oven kynnyksen eteen koonnut.

Ehtimättä kuulla Lotan kirouksia ja toraa säntäsi kovin pelästynyt


emäntä tyttärensä luo. Liili kietoi käsivartensa hänen kaulansa
ympäri ja sai kyyneliltään tuskin nyyhkityksi: »Pikku viikate on paha,
se puree.»

Äiti repäsi silmänräpäyksessä paidan pienosen päältä. Ei Liilissä


mitään haavaa näkynyt. »Mihin puri paha viikate Liiliä?»

»Ei Liiliä, mutta Lottaa.»


»Jumalan kiitos!» huudahti emäntä, kun hän oli tullut
vakuutetuksi, ettei mitään onnettomuutta ollut Liilille tapahtunut. Ja
hänestä tuntuivat nyt kaikki entiset onnettomuudet hyvin pieniltä.
Mutta toisilla silmillä katsoi Karja-Lotta asiaa. Hän ei vihaltansa
muistanut voivottaakaan.

»Vai Jumalan kiitos! Vai … vai… Olisitte kai suonut, että olisin
astunut molemmat jalkani… Vai Jumalan kiitos!» Ja vihan vimmassa
repi hän pois siteen haavalta ja ojensi jalkansa emäntää kohden.
»Siinä sen näette, mitä tyttökakaranne on aikaan saanut!» —
Jalkapöytä oli miltei kahtia leikattu; haava oli kauhea, ja verta siitä
pillinään ruiskusi lattialle.

»Tervaa, missä on tervasanko?» huusi Jussi.

»Tervaa sinä suusi, vääräsuu!» ärjäsi Lotta yhä kieltänsä pieksäen


ja rupesi taasen sitomaan haavaansa. Mutta lienee hän viimeinkin
huomannut, ettei hän muiden avutta voinut toimeen tulla, sillä äkkiä
katkaisi hän sanatulvansa ja lausui maltillisemmalla äänellä: »Mene
noutamaan vettä kaivosta äläkä siinä töllistele, niinkuin et olisi sirpin
puremaa ennen nähnyt!»

Isännän kivut olivat vähän helpottaneet, kun hän omalla


vuoteellaan makasi. Hänkin oli kovin pelästynyt, kun näki Liilin
verisenä. Mutta pian käsitti hän koko tapauksen. Liili oli seisonut
sirppikasan vieressä, kun Lotta siihen astui. Koskelaa harmitti kovin
aamun tapaukset, ja kipu, minkä hän tunsi jalassaan, ilmaisi hänelle,
että se joko oli sijoiltansa, jollei poikki. Hän oli juuri lähettämäisillään
Vaarasen Kaisan lukkaria noutamaan, kun Jussi astui sisään vesikiulu
toisessa kädessään. Hän oli hiukan kalpea ja hieman vapisi käsi, kun
hän asetti kiulun Lotan viereen.
»Käykäähän veräjällä katsomassa! Kuusen havuja siinä on ja risti
maahan piirretty. Onpa siinä vielä tuohivirsutkin, käret tänne tupaan
päin…»

»Enkös minä sitä sanonut!» keskeytti Jussia Kaisa-Liisa. »Mörkö-


Maija se tämän kaiken on aikaansaanut; ja kyllä emäntä on siihen
syypää, kun ajoi pois ja manasi Hölöpän-Matin Miinaa. Risti ja havut
tietävät varmaankin kuolemaa ja virsut, että täältä se ruumis
kannetaan, koska käret tännepäin viittaavat… Kyllä sinä nyt taidat
lähtöä tehdä, Karja-Lotta; kovinpa ovat poskesi kelmeät! Oletkin
vuodattanut jo verta niin paljon, ettei luulisi ihmisessä niin paljon
löytyvän… Tahi tarkoittaisiko risti isäntää … niin, kukapa sen
tietää?… Kyllä tässä ei taida muuta neuvoa olla, kuin että emäntä
kiireesti menee Mörkö-Maijan luo ja nöyrästi pyytää häntä
peruuttamaan kovat kirouksensa.»

»Samaa mieltä minäkin», mumisi Vääräsuu-Jussi.

Kaisa-Liisan sanat olivat valtaavasti vaikuttaneet kaikkiin, itse


isäntäänkin, joka ei kumminkaan ollut taikauskoisimpia. Häntä
pelästytti kauheasti Kaisa-Liisan arvelu, että tuo risti ja havukasa
kentiesi häntä itseään tarkoitti. Karja-Lotta puhkesi ääneensä
itkemään, tunsi jo kuoleman kopristavan sydäntä. »Voi, voi, ja kun
vielä syyttömästi pitää kärsiä toisen syntien tähden!»

»Kyllä se ei taida vähemmästä käydä», lisäsi Jussin sanoihin


Silmäpuoli-Mikko. Hänen nenäänsä pakotti ylön kauheasti, ja kun
hän sitä tunnusteli, niin eipä hän ollut ihan varma, ketä tuo risti ja
havukasa oikein tarkoittivat.

Jos olisi asia riippunut Kaisa-Liisan, Vääräsuu-Jussin ja Silmäpuoli-


Mikon päätöksestä, niin olisi kaiketi emäntä paikalla lähtenyt Mörkö-
Maijan luo. Mutta eipä häntä itseään, emäntää näet, ollut muu
vahinko kohdannut kuin tuo kodassa ja kellarissa — ja olipa siinä jo
vahinkoa kerraksi. Mannen jalka oli kentiesi vaan nurjahtanut…

»Minäkö lähtisin noidan luo? En ikipäivinäni!» huudahti hän.

»Voi, voi sitä paatunutta sydäntä!» valitti Karja-Lotta ja antoi


vastustamatta jalkansa Lois-Lassin hoidettavaksi. Ja Lassi ponnisteli
miltei kaikin voiminsa, saadaksensa käärityksi oikein lujaan köyden
nilkasta ylöspäin Lotan jalan ympäri, jotta veri viimeinkin taukoisi
juoksemasta. Hän muisti joskus kuulleensa, että niin oli meneteltävä
tällaisissa tapauksissa.

»Voi, voi sitä paatunutta sydäntä! Ja minun viattoman… Oletko


riivattu, mokoma! Tahdotko vielä kuristaa poikki jalkanikin…»

»Älä sinä ole milläsikään…»

»Vai ette lähde, emäntä!» huudahti Kaisa-Liisa, joka suuresti


mieltyi siihen, että Vääräsuu-Jussi ja Silmäpuoli-Mikko pitivät hänen
puoltaan. »No, sama se! Mutta jos oikein tarkoin katselemme tuota
ristiä veräjän luona, niin olenpa varma siitä, että siinä on toinen
hyvin pieni vieressä, vaikkei Jussi sitä kiireessä huomannut; ja se
varmaan tietää jotakin. Pieni risti … ketäpä täällä pientä on, muu
kuin Liili, ja että risti häntä juuri tarkoittaa, senhän me kaikki
näimme. Sillä minkätähden hän muuten olisi niin verinen ollut, kun
tupaan astuimme… Varoitus … varoitus! Niin, menkää jos tahdotte,
emäntä, se on teidän asianne, mutta muistakaa sanani: ei Lottaa
täältä yksin kanneta.»

»Voi, voi!» valitti Lotta, joka Kaisa-Liisan ennustaessa oli pistänyt


käärityn ja kauheasti pakottavan jalkansa Jussin tuomaan
vesikiuluun.

»Mihin Lotta kannetaan, äiti?» kysyi Liili, joka oli saanut uuden
paidan yllensä ja nyt kummastellen katseli outoa näköä tuvassa.

»Hautaan, lapsi, hautaan!» sanoi Kaisa-Liisa juhlallisesti.

»Ja sinne taitaa sinunkin tiesi käydä, ennenkuin tiedätkään, Liili


parka!… Niin pieni, niin herttainen, ja katkaistaan kuin kukkanen
kentällä kuoleman viikatteella… Mitenkä se virsikirjassa
kuuluukaan?» — tokasi Kaisa-Liisan puheeseen Vaarasen Kaisa, joka
kaiken aikaa oli päivitellyt, kuinka hän vähällä oli ollut tukehtua, ja
nyt viimein huomasi, että hänenkin tulisi asiain menoihin sekaantua.

»Ole vaiti ja mene noutamaan tänne lukkari!» ärjäsi isäntä, jota


Vaarasen Kaisan ennustus kovin peloitti. »Eikä tuo taitaisi
pahemmaksi olla, jos pistäytyisit Maijan luona» — lisäsi hän, heittäen
silmäyksen vaimoonsa.

Emäntään oli niinikään kovasti koskenut Kaisa-Liisan ja Vaarasen


Kaisan ennustukset. Liilihän oli hänen ainoa lapsensa. Mutta
nöyryyttää itseään siihen määrään…

»Kävisihän päinsä, että Kaisa, kun lukkarin luota palaa, pistäytyy


Maijan luona ja … vaikka käskee hänet tänne», sanoi hän
vitkallisesti, mieheensä kääntyen.

»Kyllähän se juuri kävisi päinsä, mutta pelkäänpä vain, ettei Maija


minusta välitä», tuumaili Vaarasen Kaisa; »Maijalla on omat
meininkinsä asioista, eikä hänen puheilleen kaikki pääse.»

Emäntä, joka oli kaapannut Liilin syliinsä, rupesi nyt uudelleen


tutkimaan, eikö tyttöä todella ollut mikään kohdannut; hän ei
näkynyt olevan varma asian oikeasta laidasta. Häntä alkoi yhä
enemmän kauhistuttaa ajatus, minkä leikkuuakkojen yhteinen
ennustus oli hänessä herättänyt. Eikä hän rauhoittunut sittenkään,
vaikka hän ei tytössä mitään outoa huomannut. »Jos hänen tähtensä
Liiliä kohtaisi joku onnettomuus … se olisi kauheaa!… Jos hän voisi
tuon onnettomuuden estää menemällä Mörkö-Maijan luo…» Kuta
kauemmin hän asiaa ajatteli, sitä kiireemmästi rupesi hänen
sydämensä tykyttämään… Ihan varmaan ei Liili ollut niin
punaposkinen nyt kuin aamulla. Ja miksi ei hän pakissut ja nauranut
niinkuin ennen…

Tällä välin oli Kaisa-Liisa äkkiä pistäynyt ulkona, ja kun hän sitten
palasi tupaan, oli hämmästys nähtävänä hänen kasvoillaan.
»Menkäähän vaan tieveräjälle katsomaan!» huusi hän jo ovelta.
»Niin on kuin sanoin: kaksi ristiä siinä on, suuri ja pieni, onpa hiukan
kolmattakin.»

Ja hänen huutoansa säesti Karja-Lotan surkea: »voi, voi; voi


sentään!»

Mutta jo on aika meidän palata sen luo, joka Koskelaisten mielestä


oli kaikki nämä onnettomuudet aikaan saanut.

Mörkö-Maija — kuka oli hän?

Aamulla näimme hänen kauhistuttavassa asennossa Koskelan


vieressä olevalla metsäkukkulalla seisovan ja sitten kamalasti
nauraen sieltä lähtevän. Puolenpäivän aikaan, jos astumme pieneen,
yksinäiseen mökkiin, joka sijaitsee noin 5-6 virstaa Koskelasta,
pienen Ummetlammen rannalla, näemme hänet uudelleen.
Hänen ulkomuotoansa olen jo koettanut kuvata. Mutta — nyt ei
säkenöitse pieni, harmaa silmä, eikä käsi ole vihaan ojennettu.
Lempeään hymyyn ovat kurttuiset, keltaiset posket vetäyneet.
Nytkin, niinkuin aamulla, liikkuvat hänen huulensa, mutta tällä kertaa
ei kiroussanoja lausuaksensa.

Mökki, jossa hän asuu, on pieni. Köyhyys puhuu siellä äänetöntä


kieltänsä, jos minne silmänsä luo. Mutta lämmin hohde loistaa
vanhuksen katseesta, ja tunteellinen on hänen äänensä.

»Niin, niin!» lausuu hän vanhalle, ryysyiselle miehelle, joka istuu


pankolla takan vieressä, piippunysä suussaan; »kyllä sen muistat,
Samuli! Yhdessähän palvelimme vallesmannissa, joka ei silloin ollut
kova kuin nyt. Vasta sitten muuttui hänen mielensä, kun hyvä rouva
kuoli. Silloin olit sinä kunnon poika, eikä minua silloin noituudesta
syytetty.»

Samuliksi sanottu ei puhunut mitään, veteli vaan savuja


piipustansa.

»Mutta sitten tuli toinen aika», jatkoi Maija suruisella äänellä.


»Sinä jätit minun ja valitsit toisen. Luulit, ettei se minuun
koskenut!… Voin sen kyllä sanoa nyt: minä surin. Ja sitten sairastuin
— sen tiedät. Olin mielenviassa, sanottiin. Ja taisinpa kyllä ollakin.
Parikymmentä vuotta on kulunut elämästäni, josta ajasta en niin
mitään muista. Ja kun viimein muistini palasi, olin minä myyty —
Leena-muorin hoidettavaksi. Sinä silloin elit ylellisyydessä vielä. Minä
näin sinut joskus; mutta ethän sinä luonut silmiäsikään — Mörkö-
Maijaan! Minä kärsin nälkää ja vilua, mutta en valittanut. Koetin
auttaa parhaan kykyni mukaan häntä, joka oli minut
elätettäväksensä ostanut, vaikka sainkin toraa ja kirouksia
palkinnoksi. Näin kyllä, että muori oli hyvissä varoissa, vaikka hän
aina köyhyyttänsä valitti; tiesin, missä hän salasi aarteensa, jotka
päivä päivältä lisääntyivät, vaikk'en ollut siitä tietävinäni; olihan
minulla selvillä, millä hän varojaan kokoili. Pilkka ja häpeä, jota
kaikkialla sain kärsiä, kun kuljin hänen asioillaan, olisi paaduttanut
monen muun sydäntä; minuun vaikutti se toista. Minä muistin sinun
käytöstäsi; kaikkialla ympärilläni näin pahaa vain, yhä pahaa — ja
minä ihmettelin, että hyvä Jumala saattoi tätä kaikkea kärsiä.

»Salaa kulki meillä siihen aikaan ihmisiä ja usein kaukaa, hyvinkin


kaukaa; ja kaikki menivät pois tyytyväisinä. He olivat saaneet, mitä
halusivat. Minut lähetti muori aina ulos, kun joku hänen luokseen
tuli, etten muka pääsisi hänen salaisuuksiensa perille. Väliin taasen
salpasi hän minut sisään milloin yöksi, milloin koko vuorokaudeksi,
kun itse salaperäisille matkoillensa lähti — varsinkin uuden kuun
aikoina. Minä seurasin häntä kerran hänen tietämättänsä. Hänen
tiensä vei kirkkomaalle. Sieltä toi hän, mitä hän tarvitsi.
Kauhistuneena seisoin siinä kirkkopihan veräjällä. Oli kuutamoyö…
Siinä opin loitsiaksi. Hänen manauksensa soivat vielä korvissani. Noin
pari viikkoa sitä ennen oli Varvasmäen isäntä käynyt meillä. Hän oli
riidoin naapurinsa kanssa ja turvasi nyt Leenaan. Ja Leena oli
luvannut auttaa häntä. Nyt auttoi hän — miten, sitä sinun ei tarvitse
tietää… Minusta oli se kauheaa. Eihän Varvasmäen toinen asukas
ollut tehnyt mitään pahaa Leenalle… Kolme päivää myöhemmin paloi
hänen asuntonsa ja karjansa, ja hän oli kerjäläinen. Siitä päivästä
rupesin minäkin manaajaksi, mutta tehdäkseni tyhjäksi Leena-
muorin aikeet. Niitä pidin aina silmällä. Hänen tietämättänsä opin
hänen tietonsa, ja omat havaintoni ovat minua eteenpäin vieneet…
Olin mahdikas, sanoit sen: mutta jos olen mahtiani mihinkään
käyttänyt, en koskaan muuhun kuin pahan ehkäisemiseen, pahojen
kiroomiseen, hyvää tehdäkseni.»
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.

More than just a book-buying platform, we strive to be a bridge


connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.

Join us on a journey of knowledge exploration, passion nurturing, and


personal growth every day!

ebookbell.com

You might also like